复合模式和装饰模式之间的区别?
复合模式和装饰模式之间有什么区别?
他们通常交手。 因为使用复合模式往往导致也使用装饰模式。
组合模式允许您以允许外部代码将整个结构视为单个实体的方式构build分层结构(如元素树)。 所以叶子实体的接口和复合实体的实体完全一样。 所以其实质就是你的复合结构中的所有元素都有相同的接口,即使有些是叶节点而其他的都是整个结构。 用户界面通常使用这种方法来简化组合。
http://en.wikipedia.org/wiki/Composite_pattern
装饰器模式允许一个实体完全包含另一个实体,以便使用装饰器看起来与包含的实体相同。 这允许修饰器修改其封装的行为和/或内容,而不改变实体的外观。 例如,您可以使用装饰器在包含元素的用法上添加日志logging输出,而不更改包含元素的任何行为。
复合模式和装饰器的结构看起来一样,但意图不同。
Composite为叶子和复合提供了一个统一的接口。
装饰者装饰赋予叶子额外的function,同时给予统一的界面。
例子
复合模式 :经典的Windows文件夹和文件。 Windows文件夹是复合材料。 文件是叶子。 双击其中任何一个打开文件/文件夹 – 双击是统一的界面。
装饰模式 :Buffered io – java.io.FileWriter
和java.io.BufferedWriter
都扩展了java.io.Writer
。 java.io.BufferedWriter
是复合的, FileWriter
是叶。 BufferedWriter
为FileWriter
添加了额外的BufferedWriter
责任(或function)。 write()
方法是统一的接口,而缓冲是附加function。
一个装饰器可以被视为一个只有一个组件的退化组合。 然而,装饰器增加了额外的责任 – 它不适用于对象聚合。
这就是四人帮的“可重用面向对象软件的devise模式 – 要素”所说的内容。
差异可能是更多目的而不是实现。 在某些情况下,复合模式比子类更好。 例如,可以通过向其添加其他类的实例,然后通过转发接口公开function来添加您希望类具有的function。
装饰器允许你透明地向一个类添加function,通常是一个单一的function,而不需要类的实例的客户端需要知道那里有一个装饰器 – 例如,在Django的视图上的“login_required”装饰器引发一个exception如果用户没有login,但是否则该视图的行为就像没有装饰器一样。
在这两种情况下,你都有一个对象embedded到另一个对象中,但是你试图完成的事情是有争议的。
结构上的差异
以下是使用PlantUML复制的GoF书籍的类图。
意图的差异
Decorator的意图是装饰一个单独的组件(UML图真的应该为装饰组件显示多个),而Composite的目的是在Composite中将组件作为一个整体进行分组(同样,UML应该显示包含一个或多个组件的复合材料)。
装饰者的目标是通过ConcreteDecorators添加行为(增强Operation()
方法的行为),而Composite则旨在收集组件。
装饰器模式可以用来静态地(或者在某些情况下在运行时)独立于同一类的其他实例扩展(装饰)某个对象的function。
这可能是由于组合:装饰包含组件,同时它实现组件接口。
Composite模式描述了一组对象将以与对象的单个实例相同的方式进行处理。 组合的目的是将对象“合成”到树结构中以表示部分 – 整体层次结构。
实现组合模式可以使客户端统一处理各个对象和组合。
尽pipe结构似乎相同,但意图和用例是不同的。
Decorator模式的用例:
- 对象的职责和行为应该dynamic添加/删除
- 具体实施应该与责任和行为分离
- 子类化过于昂贵,无法dynamic添加/移除职责
这两种模式的主要区别在于:
- 装饰器的目的是让你没有任何子类的责任。 复合材料的重点不在于点缀,而在于performance
- 修饰者添加/删除额外的责任 – 它不是用于对象聚合。
为了更好地理解SE在SE中有用的post
IO的装饰模式
何时使用装饰模式?