Java抽象类或静态实用类设计选择

我正在实施一些具有一些共同行为的战略(战略模式) ,并且尚未确定共同运营应该存在的地方。

  • 假设我有1个上下文和3个策略,策略中使用的一些操作是共享的,有些仅需要2个其他操作,只需要1个策略。
  • 没有成员级别的状态共享,因此唯一的操作实际上是无状态的。
  • 操作的目的是支持将状态格式化为文件,例如视图助手。

选项1:创建一个AbstractStrategy类

  • 我正在使用Java,因此将来会立即使用此function。
  • inheritance倾向于导致。 在一个山脊结构。
  • 操作将是最终的。

选项2:创建一个Util类的静态助手

  • 灵活,但由于某种原因感觉像代码味道。
  • 没有山脊。

任何建议或偏好?

请注意,我正在处理的级别是策略级别,而不是上下文级别(请参阅维基百科链接)。

有一个原因……一个很大的原因……在抽象类或接口上使用静态Util类。

因此,您可以在以后添加更多方法。

使用抽象类或接口,必须在从其inheritance的所有类中更改对该类/接口所做的任何更改。 如果您正在编写公共API,这尤其成问题。

Java框架具有分散在其中的静态方法的util类。 最着名的是java.util包: CollectionsArrays

有很多方法可以实现这一目标。

  1. 使用抽象类并将执行的变量部分变为抽象方法=>某些策略将实现所有操作(通过覆盖抽象方法),而其他策略可以跳过可选的操作。 请注意,在这种情况下,可选操作可以是空钩子方法而不是抽象方法。 这样你就可以避免在子类中将这些操作实现为空方法的麻烦。

  2. 使用实际的“策略”界面(使用您指向的维基百科文章中的执行方法)。 然后,客户端类将由策略的实现提供(可以是匿名内部类或实际的完整策略类)。

第一种更直接但更严格:如果必须修改操作数(特别是抽象操作数),则必须更新所有子类。

第二种是更灵活,但你必须找到一种方法,通过委派或使用静态实用方法来“共享”不同策略之间的常见操作。

除了您列出的两个选项之外,还有另一个选项:

在我看来,你会喜欢某种组合,你可以只使用你需要的function。 也许您可以使用命令模式打包您的操作,然后从这些组合您的策略?

优点:

  • 战略inheritance不是必需的。
  • 策略将无法查看未使用/隐藏的“共享方法”。
  • 没有静态实用程序类与混杂的(可能)无关的方法。
  • 更简单的unit testing – 可以单独测试操作。
  • 简单的共享策略类,它迭代操作。

缺点:

  • 附加课程。
  • 操作必须符合可能是限制性的公共命令接口。
  • 对于非常简单的操作来说可能有点过头了 – 你的格式化程序可能就是这样。

如果它被声明为Abstract ,人们可能会猜测它是为扩展而设计的。 因此,声明一个私有构造函数是一个更好的主意。