复合模式和装饰器模式的区别?
Posted
技术标签:
【中文标题】复合模式和装饰器模式的区别?【英文标题】:Difference between the Composite Pattern and Decorator Pattern? 【发布时间】:2011-01-15 02:12:43 【问题描述】:复合模式和装饰器模式有什么区别?
【问题讨论】:
okey-pafsd07.blogspot.com/2007/03/… 它们是完全不同的模式。Composite
旨在将多个对象组合并表示为单个对象(具有相同的基本类型) - 即 1 到多个,而 Decorator
增强(或在其之上添加)相同类型的单个对象的能力- 即1比1。你应该问Decorator
和Proxy
有什么区别,它们更相似。
@Hristo 我认为完全不同是夸大其词。并排看它们,它们在结构上非常相似。唯一的主要区别在于我们如何将其原因置于上下文中。
【参考方案1】:
composite 模式和 decorator 的结构看起来一样,但意图不同。
Composite 为叶子和复合物提供统一的接口。
装饰器装饰器为叶子提供了额外的功能,同时提供了统一的界面。
示例
复合模式:经典的 windows 文件夹和文件。 Windows 文件夹是复合的。文件是叶子。双击其中任何一个打开文件/文件夹 - 双击是统一界面。
装饰器模式:缓冲 io - java.io.FileWriter
和 java.io.BufferedWriter
都扩展 java.io.Writer
。 java.io.BufferedWriter
是复合的,FileWriter
是叶子。 BufferedWriter
为FileWriter
添加了额外的缓冲职责(或功能)。
write()
方法是统一接口,而缓冲是附加特性。
【讨论】:
关键字unified interface
是一个强大的短语,与Facade
DP 搭配起来比Composite 和Decorator 更适合。关键字很强大,如果使用不当,可能会产生误导。【参考方案2】:
他们通常齐头并进。因为使用复合模式通常会导致也使用装饰器模式。
复合模式允许您以允许外部代码将整个结构视为单个实体的方式构建层次结构(例如元素树)。因此,叶实体的接口与复合实体的实体完全相同。所以本质是复合结构中的所有元素都具有相同的接口,即使有些是叶节点而另一些是整个结构。用户界面通常使用这种方法来实现轻松的可组合性。
http://en.wikipedia.org/wiki/Composite_pattern
装饰器模式允许一个实体完全包含另一个实体,以便使用装饰器看起来与包含的实体相同。这允许装饰器在不改变实体外观的情况下修改它所封装的任何内容的行为和/或内容。例如,您可以使用装饰器在包含元素的使用情况下添加日志输出,而不会更改包含元素的任何行为。
http://en.wikipedia.org/wiki/Decorator_pattern
【讨论】:
对我来说,这个答案中最有趣的是你在 gof book 中写道('他们通常齐头并进。因为使用复合模式通常会导致也使用装饰模式')你可以查看 Composite 和 Decorator 之间的依赖关系。 Composite 可以使用 Decorator 向对象添加职责(它在图上具有模式之间的依赖关系)。您能否提供一个实现示例(或类图)。因为我不确定 gof 的作者到底在想什么。【参考方案3】:装饰器可以被视为只有一个组件的退化组合。然而,装饰器增加了额外的职责——它不适合对象聚合。
这就是四人组在“可重用面向对象软件的设计模式-元素”中所说的。
【讨论】:
【参考方案4】:区别可能更多是目的而不是实现。在某些情况下,复合模式比子类化更可取。例如,您可以通过向其添加其他类的实例,然后通过转发接口公开该功能来添加您希望某个类具有的功能。
装饰器允许您透明地向类添加功能,通常是单个功能,而类实例的客户端不需要知道那里有装饰器 - 例如,Django 中视图上的“login_required”装饰器如果用户未登录,则引发异常,否则视图的行为与没有装饰器时一样。
在这两种情况下,您都将一个对象嵌入到另一个对象中,但您尝试完成的任务可能会有所不同。
【讨论】:
【参考方案5】:结构差异
这是 GoF 书中的类图,使用 PlantUML 复制。
意图不同
Decorator 的目的是装饰一个 单个 组件(UML 图确实应该为被装饰的组件显示多个一个),而 Composite 的目的是将组件作为一个整体分组组合(同样,UML 应该显示一个包含一个或多个组件的组合)。
Decorator 的目标是通过 ConcreteDecorators 添加行为(增强 Operation()
方法的行为),而 Composite 旨在收集组件。
【讨论】:
【参考方案6】:Decorator 模式可用于静态扩展(装饰)某个对象的功能,或者在某些情况下在运行时独立于同一类的其他实例。
这可能是由于组合:装饰器包含组件,同时它实现了组件接口。
Composite 模式描述了一组对象的处理方式与对象的单个实例相同。组合的目的是将对象“组合”成树状结构,以表示部分整体的层次结构。
实施复合模式可以让客户统一对待单个对象和组合。
尽管结构似乎相同,但意图和用例却不同。
Decorator 模式的用例:
-
应动态添加/删除对象职责和行为
具体实施应与职责和行为分离
子类化成本太高,无法动态添加/删除职责
这两种模式之间的键differences :
-
装饰器旨在让您无需子类化即可向对象添加职责。 Composite 的重点不是装饰,而是表现
装饰器添加/删除额外职责 - 它不适用于对象聚合。
SE 中有用的帖子,有助于更好地理解:
Decorator Pattern for IO
When to Use the Decorator Pattern?
【讨论】:
【参考方案7】:复合:
是使用递归的树结构。 Leaf 和 Composite 具有相同的接口 对象之间的统一装饰者:
包含另一个实体。 在不修改复合对象的情况下向复合对象添加新功能。【讨论】:
以上是关于复合模式和装饰器模式的区别?的主要内容,如果未能解决你的问题,请参考以下文章