【问题标题】:Use decorator and factory together to add properties or specialize an object一起使用装饰器和工厂来添加属性或专门化一个对象
【发布时间】:2012-11-25 12:08:02
【问题描述】:

我是 OOP 和设计模式的新手。

我有一个简单的应用程序来处理表、列(属于表)、行(属于列)和值(属于行)的生成。这些对象中的每一个都可以是 Property 的集合,而 Property 又被定义为枚举。

它们都是接口:我使用工厂来获取这些产品的具体实例。

现在我面临扩展这些类的问题。假设我需要另一个名为“SpecialTable”的产品,它又具有一些特殊属性或新方法,如“getSomethingSpecial”或一组扩展的属性。唯一的方法是扩展/专门化我的所有元素(即构建一个 SpecialTableFactory、一个 SpecialTable 接口和一个 SpecialTableImpl 具体)?假设我仍然想使用不需要继承的标准方法,例如 addRow(column, name)...

我不喜欢继承工厂和接口的想法,但由于 SpecialTable 有更多的方法,我猜它不能共享同一个工厂。我错了吗?

另一个问题:如果我需要在运行时定义产品属性(升级到 SpecialTable 的 Table),我想我应该使用装饰器。是否可以(以及如何)将工厂设计和装饰设计结合起来?

【问题讨论】:

  • 也许我意识到问题应该出在programmers.stackoverflow.com上

标签: oop design-patterns decorator factory-pattern dataabstract


【解决方案1】:

SpecialTable 需要自己的创建机制,所以是的,它需要自己的工厂方法(或工厂类,如果您要创建一组必须相关的项目)。

或者:您可以为您的工厂使用设计模式策略。在这种情况下,您可以在运行时使用所需的创建机制来配置工厂。

至于剩下的问题:

向类添加功能的三种最常用方法是:

  1. 子类化
  2. 设计模式适配器/代理,可能与自省相结合。类别确实是这种方法的一个特例。
  3. 设计模式访问者

您已经考虑过子类化。

设计模式 Adaptor/Proxy 基本上是这样的:创建一个具有所需接口的新类,并通过调用现有类的实例来实现其部分(或全部)方法。

对于设计模式访问者,您在某种意义上将代理与“双重调度”结合起来。您添加的函数驻留在可以调用现有类的实例的对象中。示例见Visitor pattern - adding new ConcreteElement classes is hard?

策略:

它是这样工作的:

public interface MyStrategyInterface {
  public void doWork();
}

public class MyStrategyAccessPoint implements MyStrategyInterface {

  private MyStrategyInterface current;

  public MyStrategyAccessPoint(final MyStrategyInterface initial) {
    current = initial;
  }

  public void doWork() {
    current.doWork();
  }

  public void setStrategy(final MyStrategyInterface newCurrent) {
    current = newCurrent;
  }
}

如您所见,您现在可以更改在运行时使用的 MyStrategyInterface 的实际实现。这种模式通常与 Singleton 结合使用,使 MyStrategyAccessPoint 及其 doWork 方法成为静态的。

【讨论】:

  • tnx!您的解释很清楚,就像淡水一样,似乎访客应该很好用(老实说,我不确定我是否理解策略)。假设 table 是一个带有 accept 方法的可访问对象,SpecialBehaviour 是一个访问者,它标识了一个特殊的 table。我会使用类似 table.accept(specialbehaviour) 的东西。但是由于这实际上并没有装饰表,所以我应该实现一个方法 specialbehaviour.getSpecialTable 来构建一个 SpecialTable 实例。这是使用模式的正确方法还是我错了?
  • 是的。有了访客,您无需进行装饰。 “装饰”在访问者中,在本例中为 SpecialBehavior。有时,扩展或子类化某些类是不可能或不方便的,Visitor 提供了一种替代方法。恰当的例子:如果您正在实现一种访问一组节点(您的基本类)的编程语言,您将无法在编译时知道编写了什么代码。访客将是答案。编译后的代码将是访问者...
猜你喜欢
  • 2020-10-04
  • 1970-01-01
  • 2019-10-08
  • 2013-02-15
  • 2013-09-19
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多