使用装饰器和工厂一起添加属性或专门化对象

时间:2012-11-25 12:08:02

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

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:3)

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

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

至于剩下的问题:

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

  1. 子类
  2. 设计模式适配器/代理,可能与内省相结合。类别确实是这种方法的特例。
  3. 设计模式访客
  4. 您已经考虑过继承。

    设计模式Adapter / 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方法保持静态。