我们什么时候需要装饰模式?

bra*_*ess 31 design-patterns decorator

什么时候需要使用装饰模式?如果可能的话,给我一个非常适合该模式的真实世界示例.

Noe*_*l M 51

Java中的Streams - 子类InputStreamOutputStream装饰模式的完美示例.

例如,将文件写入磁盘:

File toWriteTo = new File("C:\\temp\\tempFile.txt");
OutputStream outputStream = new FileOutputStream(toWriteTo);    

outputStream.write("Sample text".getBytes());
Run Code Online (Sandbox Code Playgroud)

那么你是否需要一些关于写入磁盘的额外功能:

File toWriteTo = new File("C:\\temp\\tempFile.txt");
OutputStream outputStream = 
             new GZIPOutputStream(new FileOutputStream(toWriteTo));

outputStream.write("Sample text".getBytes());
Run Code Online (Sandbox Code Playgroud)

通过简单地"链接"构造函数,您可以创建非常强大的写入磁盘的方法.这种方式的优点在于您可以在OutputStream以后添加不同的(在此示例中)实现.此外,每个实现都不知道其他实现如何工作 - 它们都只适用于同一个合同.这也使得单独测试每个实现非常容易.


有很多"真实世界"的例子可以使用装饰器模式.在我的头顶,一些例子:

  • 读写磁盘(上图)
  • 构建UI元素,例如在文本区域上添加滚动条等

Head First Design Patterns有一些更"真实世界"的例子.似乎O'Reilly有免费提供的样本章节,这是装饰模式.谷歌出现了这个链接:PDF

  • 是的,java.io完全是关于Decorator的. (5认同)

use*_*515 20

两个现实生活中的例子:

"暗黑破坏神2"和"最终幻想7"中的物品升级系统.武器和装甲都有插座或插槽.在游戏过程中,玩家将升级(宝石,符文或材料)放入这些插槽中.每次升级都有单独的效果(例如,8点火焰伤害或10%法力水蛭).因此,当你挥动你的剑时,它会造成基础伤害加上你添加的每次升级所增加的伤害.这非常接近地匹配装饰器模式.


Mik*_*ike 8

来自四人帮:

例如,图形用户界面工具包应该允许您添加边框或行为等属性,例如滚动到任何用户界面组件.

...

装饰器符合它装饰的组件的接口,因此它的存在对组件的客户端是透明的.装饰器将请求转发给组件,并且可以在转发之前或之后执行附加动作(例如绘制边界).透明度允许您递归地嵌套装饰器,从而允许无限数量的增加的职责.

  • 现实世界中的UI是否使用这种装饰器? (2认同)

Laz*_*rus 5

看看福勒的描述; 它提供了一个关于书籍/视频和装饰"可借"的具体例子,你可以在这里找到它.