最近,我读到了关于装饰设计模式的文章,但是留下了一些我在网上找不到的未回答的问题。我不打算显示代码,因为我不想让这个问题变得比实际更复杂。我只举一个例子:
地铁商店:
组件--> SubSandwich
ConcreteComponent ->15 15cmSub,30 15cmSub
装饰器->成分
ConcreteDecorator ->白奶酪,黄奶酪,果酱,鸡肉。。
这就是地铁商店的工作方式。选择你的核心砂子大小,然后添加所有你喜欢的配料。但我还有一些问题:
发布于 2016-06-05 17:24:51
那么装饰模式可能不是你要找的东西。修饰器是指在不改变界面的情况下进行合成行为。它不是关于连接属性,而且它不能很好地工作,因为只有最外层的装饰实例(通常)可以直接提供给用户。如果您需要知道SubWithProvolone是否包装了SubWithTurkey --或者其他特定类型的子包--那么您就做错了。
我所知道的最好的示例是Java /O类InputStream、OutputStream、Reader和Writer及其所有子类。任何InputStream都可以通过装饰BufferedInputStream来缓冲;任何InputStream都可以用InputStreamReader装饰成Reader;等等。
但是,如果你开始加入规则,比如“BufferedWriter不能被另一个BufferedWriter修饰”(假设的),那么它就会崩溃--只是没有好的方法来执行它,而且实际上,对该规则没有真正的需要。如果您试图对这样的情况进行建模,对于如何组合组件这样的规则是真正需要的,那么Decorator并不是一个很好的匹配。
这与#1的问题本质上是一样的,你也许可以一起解决这个问题和前一个问题,但是如果这些问题本身就出现了,那么Decorator就不适合这种情况了。
你问题的其他方面有点宽泛,但这个问题太宽泛了。我们回答有关编程细节的具体问题。
你问的是错误的二分法。Java区分接口和纯抽象类是一种肤浅的语言设计细节,主要用于支持Java对实现的单个继承的限制。如果您的问题被重定向到C++,那么接口和纯粹的抽象类之间并没有很大的差别,而设计模式也同样适用于这些类。您可以围绕作为Java接口的基本类型实现Decorator模式。
尽管如此,我前面提到的Java I/O类确实使用了类而不是接口。有优点也有缺点,但优点之一是它允许他们使用模板方法模式来提供更容易实现的具体实现类。然而,即使在那里,也可以为此目的提供抽象基类,即使装饰器类型被声明为接口。
发布于 2016-06-05 16:53:05
其原有结构中的模式并没有解决任何实际问题。你需要把它们和一般的坚实的原则结合起来。对于示例问题,可以在Decorator之上实现Builder模式。你会有一些DSL类型的代码。
Builder.aPizza().withCheeze(someCheeze).addTopping(someTopping).and(someOtherTopping).build();使用这种模式/样式,您可以验证对象的中间状态,甚至可以在调用build()方法的最后阶段验证。
发布于 2016-06-05 17:04:03
Collections.synchronizedList(List list),它通过包装一个synchronized块来“装饰”所有方法。
您可能仍然可以在您描述的用例中使用一个装饰器,但是每个装饰步骤都必须检查它是否可以应用,如果不是,则抛出。
老实说,我甚至不知道为什么这类例子如此受欢迎。我还没见过像这样的装饰图案。它不是为添加组件而制作的。ListItem对象,您希望使用库B来显示它们。你既不能改变A生产什么,也不能改变B消耗它们的方式。但是,当您不喜欢A如何实现B用来显示的toString()方法时,您可以简单地包装一个新的toString()方法。它仍然是一个ListItem,所以B不会注意到,就像A也没有注意到任何东西一样。https://stackoverflow.com/questions/37644223
复制相似问题