复合图案和装饰图案之间有什么区别?
答案 0 :(得分:40)
他们通常会交到手中。因为使用复合图案经常导致也使用装饰图案。
复合模式允许您以允许外部代码将整个结构作为单个实体查看的方式构建层次结构(例如元素树)。因此,叶实体的接口与复合实体的实体完全相同。因此,本质上是复合结构中的所有元素都具有相同的接口,即使有些是叶节点而其他元素是整个结构。用户界面通常使用这种方法来实现易于组合。
http://en.wikipedia.org/wiki/Composite_pattern
装饰器模式允许实体完全包含另一个实体,以便使用装饰器看起来与包含的实体相同。这允许装饰器修改其封装的任何内容的行为和/或内容,而不改变实体的外观。例如,您可以使用装饰器在包含元素的使用上添加日志输出,而不更改所包含元素的任何行为。
答案 1 :(得分:39)
复合模式和装饰器的结构看起来相同,但它们有不同的意图。
复合为叶子和复合提供统一的接口。
装饰器装饰器为leaf提供了额外的功能,同时提供了统一的界面。
复合模式:经典的Windows文件夹和文件。 Windows文件夹是复合材料。文件是叶子。双击其中任何一个打开文件/文件夹 - 双击是统一界面。
装饰器模式:缓冲io - java.io.FileWriter
和java.io.BufferedWriter
都延伸java.io.Writer
。 java.io.BufferedWriter
是复合的,FileWriter
是leaf。 BufferedWriter
为FileWriter
添加了缓冲的额外责任(或功能)。
write()
方法是统一接口,而缓冲是附加功能。
答案 2 :(得分:18)
装饰器可以看作是只有一个组件的简并复合。但是,装饰器增加了额外的职责 - 它不适用于对象聚合。
这是四人帮中“设计模式 - 可重用面向对象软件的元素”中所说的。
答案 3 :(得分:5)
差异可能更多的是目的而不是实施。在某些情况下,复合模式优于子类化。例如,您可以通过向其添加其他类的实例来添加您希望类具有的功能,然后通过转发接口公开该功能。
装饰器允许您透明地向类添加功能(通常是单个功能),而没有类的实例的客户端需要知道那里有装饰器 - 例如,Django中的视图上的“login_required”装饰器如果用户未登录则引发异常,否则视图的行为与没有装饰器的情况一样。
在这两种情况下,你有一个对象嵌入另一个对象中,但你想要完成的事情可以说是不同的。
答案 4 :(得分:3)
以下是使用PlantUML转载的GoF书籍中的类图。
Decorator的目的是装饰单个组件(UML图实际上应该显示装饰组件的多重性),而Composite的意图是将组件整体分组。 Composite(同样,UML应该显示包含一个或多个组件的Composite)。
Decorator的目标是通过ConcreteDecorators添加行为(增强Operation()
方法的行为),而Composite则旨在收集组件。
答案 5 :(得分:1)
from __future__ import unicode_literals
模式可用于静态地(或在某些情况下)在运行时扩展(装饰)某个对象的功能,而与同一类的其他实例无关。
由于组合可能:Decorator包含Component,同时它实现了Component接口。
Decorator模式描述了一组对象的处理方式与对象的单个实例相同。复合材料的目的是“组成”#34;将对象转换为树结构以表示部分整体层次结构。
通过实现复合模式,客户可以统一处理单个对象和组合。
即使结构看起来相同,意图和用例也不同。
Composite模式的用例:
这两种模式之间的关键Decorator:
SE中的有用帖子可以更好地理解:
答案 6 :(得分:0)
<强>组合:强>
<强>装饰:强>