关于java:使用列表而不是装饰器模式?

Using Lists Instead of Decorator Pattern?

一个来自《HeadFirst:DesignPatterns》一书的装饰模式用例让我产生了这个问题。我试着写下来:

It's a coffee shop system with some coffees and a lot of condiments
you can put in them (for an extra cost), you need to be able to order
and charge for a coffee with any condiments the costumer desires, and
to avoid having total mayhem (e.g. booleans to keep track of the
condiments) Decorator Pattern is used. We have an abstract Beverage
class, each type of coffee as concrete components and each condiment
as concrete decorators wrapping up a Beverage, like this:

Beverage Class Diagram

And so we have the following process returning a coffee cost:

Coffee Cost Delegation

我的问题是:为什么不用列表而不是装饰器来实现这个呢?我们可以在每种饮料中列出调味品的清单,并通过迭代该清单来计算成本。要订购咖啡,我们只需实例化一次并添加所需的调味品,避免声明如下:

1
2
3
4
// Using second image example
Beverage beverage = new DarkRoast(beverage);
beverage = new Mocha(beverage);
beverage = new Whip(beverage);

除此之外,如果我们不让装饰师包装咖啡,我们可以更灵活地操作,比如给咖啡打折,不包括它的调味品。这是一个长期研究的问题,我知道我错过了一些东西,或者我可能出了什么问题,所以如果你对此有任何想法,我很乐意知道并进一步讨论。


Decorator模式decorating is about an additional(增强)在运行时对象与特点。P></

already have a class你想让它Awhich,呼叫级安IAimplements接口。if there is now a an additional feature of增需求for which we have a it to想法,someAlignFeatureToA()which was not there在A。现在你有一Aoption of the class伸展。另一种方法是Compositionwhich should be favoured Inheritance过。你可以Aof the class对象包在一级Bof the same as implwmenting InterfaceAIA即。这样会好的客户端代码:for the of the对象易接受EN has the same as B级接口(as of a。假设队列is which is the depends阱written on the abstractions(接口和类的IA)类的具体类Anot on)。P></

* is not the继承链太长,你可以添加额外的功能和在运行时easily。P></

现在问题来了:你是在the example你把你的问题,但我觉得更好的FITS list,its the author of the使用意向的解释模式decorator with example of an easy。认为咖啡是自制咖啡和牛奶混合后),糖。自制咖啡混合是继续追踪of小零件。解决方案emerges similar to the在这里组合模式。P></

decorator模式设计模式是基于增强的行为。我在Java streams行为(uses this method is by the implementation)增强(一级decorating is to another骨膜流与提高原有核酮)P></


免责声明:我使用的术语和代码片段摘自本文。

正如您注意到的,有两种可能的设计来"装饰"一个对象。这两种方法都可以实现相同的功能,主要区别在于使用的上下文。

垂直装饰

1
2
3
4
5
6
7
8
9
10
11
12
13
Numbers numbers = new Sorted(
  new Unique(
    new Odds(
      new Positive(
        new ArrayNumbers(
          new Integer[] {
            -1, 78, 4, -34, 98, 4,
          }
        )
      )
    )
  )
);

这是实现修饰符的最常见方法。我几乎完全用这种方式来实现我的装饰,因为我发现它更"自然"和简单。它适用于装饰器数量不太多的情况(多少取决于程序员的解释)。当一些对象需要动态扩展时,它也非常适合:当它在声明时不知道需要哪个装饰器时。

水平装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
Numbers numbers = new Modified(
  new ArrayNumbers(
    new Integer[] {
      -1, 78, 4, -34, 98, 4,
    }
  ),
  new Diff[] {
    new Positive(),
    new Odds(),
    new Unique(),
    new Sorted(),
  }
);

在非常罕见的情况下(当装饰师的数量开始增长时),我做出了设计选择,以"扁平化"列表状结构中的装饰师。这有利于简化代码的读取,但也有利于在运行时失去灵活性:在对象的创建过程中,需要知道要应用哪个装饰器(在不可变的上下文中尤其如此,我试图培养这种情况),因此根据应用程序的不同,这可能是不可行的。

最后,您只需在灵活性和可读性之间做出设计决策。


你是什么方式告诉is to calculate the of the饮料的总成本。在更多的通用条款,你选择proposing安路to execute MERGE &;the main of each of the源性行为目标模式模式模式decorator做茶,增上他们进入名单。与EN is not an那么点太多。P></

但原始的模式去decorator Intent to of that other比多角度广泛。functionalities is to an en增dynamically扩展对象。which means have some对象O1&;it to convert into another恩想扩展对象与功能性O2&;2 interchangeable are to be yet的那些。P></

我知道is about how we can /对象管理对象lifecycle演化对茶茶。?我希望你的想法。):)P></


You should distinguish从行为数据。P></

在decorator is of indirection层处理与特异性问题为甚。日期(在types of the条款,合同等,protocols)stays the same,but You get the implementation以更多的灵活性。你可以用decorator重用现有的功能性,在启动和增安conjunction changes with ADAPTER的地方,你可以慢慢开始从基本migrating API to a different酮产生和保持兼容。P></

我只负责for lists should to the包含日期提供接入在特异性的方式。表演的任务处理日期/日期on the the by the lists should be done包含函数/对象/类的模式有不同的责任。P></