复合模式和装饰模式之间的区别?

复合模式和装饰模式之间有什么区别?

他们通常交手。 因为使用复合模式往往导致也使用装饰模式。

组合模式允许您以允许外部代码将整个结构视为单个实体的方式构build分层结构(如元素树)。 所以叶子实体的接口和复合实体的实体完全一样。 所以其实质就是你的复合结构中的所有元素都有相同的接口,即使有些是叶节点而其他的都是整个结构。 用户界面通常使用这种方法来简化组合。

http://en.wikipedia.org/wiki/Composite_pattern

装饰器模式允许一个实体完全包含另一个实体,以便使用装饰器看起来与包含的实体相同。 这允许修饰器修改其封装的行为和/或内容,而不改变实体的外观。 例如,您可以使用装饰器在包含元素的用法上添加日志logging输出,而不更改包含元素的任何行为。

http://en.wikipedia.org/wiki/Decorator_pattern

复合模式和装饰器的结构看起来一样,但意图不同。

Composite为叶子和复合提供了一个统一的接口。

装饰者装饰赋予叶子额外的function,同时给予统一的界面。


例子

复合模式 :经典的Windows文件夹和文件。 Windows文件夹是复合材料。 文件是叶子。 双击其中任何一个打开文件/文件夹 – 双击是统一的界面。

装饰模式 :Buffered io – java.io.FileWriterjava.io.BufferedWriter都扩展了java.io.Writerjava.io.BufferedWriter是复合的, FileWriter是叶。 BufferedWriterFileWriter添加了额外的BufferedWriter责任(或function)。 write()方法是统一的接口,而缓冲是附加function。

一个装饰器可以被视为一个只有一个组件的退化组合。 然而,装饰器增加了额外的责任 – 它不适用于对象聚合。

这就是四人帮的“可重用面向对象软件的devise模式 – 要素”所说的内容。

差异可能是更多目的而不是实现。 在某些情况下,复合模式比子类更好。 例如,可以通过向其添加其他类的实例,然后通过转发接口公开function来添加您希望类具有的function。

装饰器允许你透明地向一个类添加function,通常是一个单一的function,而不需要类的实例的客户端需要知道那里有一个装饰器 – 例如,在Django的视图上的“login_required”装饰器引发一个exception如果用户没有login,但是否则该视图的行为就像没有装饰器一样。

在这两种情况下,你都有一个对象embedded到另一个对象中,但是你试图完成的事情是有争议的。

结构上的差异

以下是使用PlantUML复制的GoF书籍的类图。

GoF装饰者类图

GoF复合类图

意图的差异

Decorator的意图是装饰一个单独的组件(UML图真的应该为装饰组件显示多个),而Composite的目的是在Composite中将组件作为一个整体进行分组(同样,UML应该显示包含一个或多个组件的复合材料)。

装饰者的目标是通过ConcreteDecorators添加行为(增强Operation()方法的行为),而Composite则旨在收集组件。

装饰器模式可以用来静态地(或者在某些情况下在运行时)独立于同一类的其他实例扩展(装饰)某个对象的function。

这可能是由于组合:装饰包含组件,同时它实现组件接口。

Composite模式描述了一组对象将以与对象的单个实例相同的方式进行处理。 组合的目的是将对象“合成”到树结构中以表示部分 – 整体层次结构。

实现组合模式可以使客户端统一处理各个对象和组合。

尽pipe结构似乎相同,但意图和用例是不同的。

Decorator模式的用例:

  1. 对象的职责和行为应该dynamic添加/删除
  2. 具体实施应该与责任和行为分离
  3. 子类化过于昂贵,无法dynamic添加/移除职责

这两种模式的主要区别在于:

  1. 装饰器的目的是让你没有任何子类的责任。 复合材料的重点不在于点缀,而在于performance
  2. 修饰者添加/删除额外的责任 – 它不是用于对象聚合。

为了更好地理解SE在SE中有用的post

IO的装饰模式

何时使用装饰模式?