2010-06-17 59 views
6

我有实现ICommand {Execute}接口的命令类。几个命令有重复的代码段。我有几种选择如何干:辅助类与功能继承。最佳实践

  • 创建静态辅助类(ES)和移动重复的代码有
  • 创建一个受保护的辅助方法

,你有什么建议,为什么命令继承?

ADDED 谢谢大家谁回答,许多答案是相似和有用的!

回答

3

它完全取决于您的重复代码的性质。

你帮助函数的输入/输出是什么?它们是否在逻辑上相关的一组变量上运行?然后 - 是的,你最好创建一个基类,并将这些变量作为成员,以及相关的辅助函数集。否则,如果辅助函数中的参数不一致,那么您仍然可以将这些函数实现为静态函数,对吧?在这种情况下,我没有看到使继承复杂化的原因,我只是用辅助函数来做到这一点(或者,如果你的语言没有把函数当作第一类公民,就使用静态辅助类)。

3

如果有任何机会,层次结构外的其他类也可能需要重复逻辑,那么我会把它放到静态帮助器类中。否则,在具有受保护继承的基类中。

2

在我看来,如果只涉及到该类的层次结构,并且不会在其外部使用,我会将重复代码放入基类中。如果有可能在不同的类中使用代码,那么将它移动到一个公共项目中的助手类。

享受!

5

而不是静态类另一种选择是将公共代码放入一个新类,并使用依赖注入将辅助类注入到命令中。这也适用于继承概念的构成。

+0

或者相反:使助手类成为装饰器并将命令类注入助手类。 – Ozan 2010-06-18 02:46:06

+2

+1在考虑代码重用时,不要认为“继承”,请考虑“聚合”。 – 2010-06-18 10:06:45

1

这里可能没有正确/错误的答案,但我想你可以肯定地执行它很差。这很可能取决于您的实际需求以及您的命令与另一个命令之间的关系。通常,我可能会使用基类实现和继承层次结构,假设这些命令是相关的,并且代码直接与命令本身相关,而不是某些外部实体本身应该是类。当然,他们是相关的,他们是命令,基类可以反映这一点。

但是,如果您的代码仅与不相关命令的子集共有,并且创建继承层次结构将强制建立不存在的关系,然后添加“helper”类(非静态,if可能的,以提高可测试性)将是解决该问题的完全自然的方式。您可能会发现,您可以将“帮助者”方法自然地分组到他们自己的类中。例如,如果有几种方法需要与您的认证子系统进行交互,那么您可能会为这些方法提供AuthenticationMediator。我也没有看到两者都有冲突。

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; 
} 

那么容易,我们应该更紧密结合这个实现类。如果这是一个常见的事件,那么基类可能是有意义的。

个人而言,复杂的层次结构比他们的价值更麻烦,在可维护性,易读性和重用性方面使用自己的判断,您应该没问题!

希望这会有所帮助! :)

0

无状态代码使用助手。

具有多个方法的状态相关代码使用继承。例如,当多个方法使用共享成员变量并因此保持共享状态时。

目标是减少重复代码的数量,它取决于它是什么类型的代码。然而,我真的很讨厌人们过度使用超级抽象类或者帮助函数来跳转到其他扼杀的抽象代码,这些代码被命名为“Executor”,“Invoker”,“DataConveyer”,“DataManager”,“SharedCode”。而且,不管怎样,所有这些跳跃的结果实际上都能够完成它应该做的工作,但是与彼此之间如此相互联系,以至于您不知道在哪里做出新的更改以添加此新功能。我应该做DataConveyer还是应该在DataManager中执行?

因此,黄金目标应该是,保持简单。

1

在你自己的代码中使用助手是一个不好的习惯,它来自懒惰。

唯一一个可能的情况下,你真正需要的帮手 - 是从像硒等

什么是辅助性的第三方库延长密封类的行为?这是一个静态的方法,它位于一些类别本身。

我们得到什么问题?

  1. 静态方法。单元测试有问题。例如,我们的开发人员向帮助者添加了缓存。因此,不可能简单地嘲笑这些方法,而我不得不添加许多逻辑来进行简单的嘲讽。是的,静态方法的错误用法是可能的......但是一开始没有人希望将状态添加到帮助器中。
  2. 位置。方法位于另一个类中,远离基本逻辑。这是代码设计的错误概念。

何时使用助手?当你需要扩展第三方库时不可能继承它。否则只是继承lib。

何时不使用助手?减少重复的代码。您需要将此代码移至其他服务。阅读DDD以提高重构技巧,并知道如何以最佳方式组织服务