我有一些实现ICommand {Execute}接口的命令类。有几个命令有重复的代码片段。我有几种选择如何干:
你会建议什么以及为什么?
ADDED 谢谢大家的回复,很多答案都很相似而且很有用!
答案 0 :(得分:5)
而不是静态类,另一个选择是将公共代码放在一个新类中,并使用依赖注入将helper类注入到命令中。这也与继承概念的构成有关。
答案 1 :(得分:3)
如果层次结构外的其他类可能还需要重复逻辑,我会把它放到静态帮助器类中。否则在具有受保护继承的基类中。
答案 2 :(得分:3)
在我看来,如果它只与该类层次结构相关并且不会在它之外使用,我会将重复的代码放入基类中。如果有可能在不同的类中使用代码,则将其移动到公共项目中的辅助类。
享受!
答案 3 :(得分:3)
这完全取决于重复代码的性质。
助手功能的输入/输出是什么?它们是否在逻辑相关的变量集上运行?然后 - 是的,你最好创建一个基类,将这些变量作为成员,以及相关的辅助函数集。
否则,如果辅助函数中的参数不一致,那么无论如何都要将这些函数实现为静态函数,对吧?在这种情况下,我没有看到使继承复杂化的原因,我只使用辅助函数(或者,如果您的语言不将函数视为一等公民,则使用静态帮助程序类)。
答案 4 :(得分:1)
这里可能没有正确/错误的答案,但我想你肯定可以很好地实现它。它可能非常依赖于您的实际要求以及您的命令彼此之间的关系。通常,我可能会使用基类实现和继承层次结构,假设命令是相关的,并且代码直接与命令本身相关,而不是与某些本身应该是类的外部实体相关。当然,它们与命令有关,基类可以反映出来。
如果你的代码只对不相关命令的子集是通用的,那么创建一个继承层次结构会强制一个不存在的关系,然后添加一个“helper”类(如果可能的话,是非静态的) ,以提高可测试性)将是解决该问题的一种非常自然的方式。您可能会发现可以将“帮助器”方法自然地分组到自己的类中。例如,如果有几种方法需要与您的身份验证子系统进行交互,那么您可能拥有这些方法的AuthenticationMediator。我也没有看到与两者兼顾的任何冲突。
答案 5 :(得分:1)
在自己的代码中使用帮助程序是一种糟糕的做法,它来自于懒惰。
您真正需要帮助的唯一可能情况是扩展密封类的行为,如硒等第三方库。
什么是帮手?它是一种静态方法,它位于一些类本身。
我们遇到了什么问题?
何时使用助手?当您需要更换第三方库时,无法继承它。否则只需继承lib。
什么时候不使用帮手?减少重复的代码。您需要将此代码移动到另一个服务。了解DDD以提高重构技能,并了解如何以最佳方式管理服务
答案 6 :(得分:0)
如果逻辑在接口成员上运行,而不是实现成员,则建议编写辅助方法[或扩展方法]。
public IRandom
{
byte NextByte ();
}
public static class IRandomExtensions
{
// logic that acts against public interface IRandom
// may be applied to all implementations
public static int GetNextUnbiasedInteger (this IRandom random) { }
public static IEnumerable<T> Shuffle<T> (
this IRandom random,
IEnumerable<T> items) { }
}
如果业务逻辑针对实现成员进行操作,
public class SomeCommand : ICommand
{
// an implementation-specific member, NOT a member
// of ICommand
public int SomeControlCount { get; set; }
}
// a method that references implementation-speciic
// details. where should this go?
public void DoSomething ()
{
SomeCommand command;
int count = command.SomeControlCount;
}
那么我们可能应该将它更紧密地绑定到实现类。如果这是一个常见的事件,那么基类可能是有意义的。
就个人而言,复杂的层次结构比它们的价值更麻烦,在可维护性,易读性和重用性方面使用自己的判断,你应该没问题!
希望这有帮助! :)
答案 7 :(得分:0)
无状态代码使用助手。
具有多个方法的状态依赖代码使用继承。例如,当多个方法使用共享成员变量并因此维持共享状态时。
目标是减少重复代码的数量,这取决于它是什么类型的代码。然而,当人们过度使用这个并制作超级抽象类或辅助函数时,我真的很讨厌,这些函数可以跳转到其他扼杀抽象代码,这些代码的名称类似于&#34; Executor&#34; &#34;祈求&#34; &#34; DataConveyer&#34; &#34;的DataManager&#34; &#34; SharedCode&#34 ;.并且在所有这些跳转的最后,实际上设法完成了它应该做的工作,但是彼此之间是如此互联,以至于你不确定在哪里进行新的更改以添加这个新功能。我应该使用DataConveyer还是应该在DataManager中执行此操作?
所以黄金目标应该是,保持简单。