`

设计模式笔记:好玩的Decorator模式

阅读更多

《设计模式》对Decorator的描述:动态给一个对象添加一些额外职责。就添加功能来说,Decorator模式比生成子类更灵活。

Decorator让我感觉设计者非常聪明,这是个好有趣聪慧的模式,马上看例子:


1.不使用Decorator模式的设计:

a.需求:打印正文

java 代码
  1. public class Ticket{
  2. public void prtTicket(){
  3. System.out.println("Sales Ticket" );
  4. }
  5. }



b.需求改变:打印正文前,先打印Header

java 代码
  1. public class Ticket{
  2. public void prtTicket(){
  3. System.out.println("Header" );
  4. System.out.println("Sales Ticket" );
  5. }
  6. }


c.需求再度改变:正文后打印Footer

java 代码
  1. public class Ticket{
  2. public void prtTicket(){
  3. System.out.println("Header" );
  4. System.out.println("Sales Ticket" );
  5. System.out.println("Footer" );
  6. }
  7. }



2.使用Decorator后的设计:

java 代码
  1. abstract public class Component{
  2. abstract public void prtTicket();
  3. }
  4. abstract public class TicketDecorator extend Component {
  5. private Component myTrailer;
  6. public TicketDecorator(Component comp){
  7. myTrailer = comp;
  8. }
  9. public void callTrailer(){
  10. if (myTrailer != null )
  11. myTrailer.prtTicket();
  12. }
  13. }
  14. public class SaleTicket extend Component{
  15. public void prtTicket(){
  16. System.out.println("Sale Ticket" );
  17. }
  18. }
  19. public class Header extend TicketDecorator{
  20. public Header(Component comp){
  21. super (comp);
  22. }
  23. public void prtTicket(){
  24. System.out.println("Header" );
  25. super .callTrailer();
  26. }
  27. }
  28. public class Footer extend TicketDecorator{
  29. public Footer (Component comp){
  30. super (comp);
  31. }
  32. public void prtTicket(){
  33. super .callTrailer();
  34. System.out.println("Footer" );
  35. }
  36. }
  37. public class Test{
  38. public static void main(String args[]){
  39. Component c = new Header( new Footer( new SaleTicket()));
  40. c.prtTicket();
  41. }
  42. }


于是,无论添加多少个功能,每个Decorator都之关心自己的功能,我们能任意重排Decorator的顺序,无需改变任何代码。

在java io中用到了Decorator模式。

分享到:
评论
22 楼 halfmile 2008-03-21  
经典,经典,简直经典到可以被抽象出来作为描述论坛讨论贴的设计模式

wgfywin 写道
其实楼主只是在介绍菜刀的用法:以前都是用手撕的,后来用菜刀切,方便多了。
结果跟帖的人说
1,菜刀不能劈柴;
2,菜刀太锋利,搞不好把手切了。
3,有些菜用菜刀切不好,直接用手撕更好。
4,我从来都是手撕的,力道、撕出来的形状都非常棒。用菜刀切出来的东西太整齐了反不好,比如手撕包菜。
5,啥叫厨房,就是炒菜用锅,煮饭用蒸笼,煨汤用砂锅。一个好的厨房就是应该各种能配置的工具都配置齐全了。
6,一个厨房搞那么多工具干嘛,我看就一个火堆,一个钢叉就可以了。

21 楼 Nighthaven 2008-03-18  
wgfywin 写道
其实楼主只是在介绍菜刀的用法:以前都是用手撕的,后来用菜刀切,方便多了。
结果跟帖的人说
1,菜刀不能劈柴;
2,菜刀太锋利,搞不好把手切了。
3,有些菜用菜刀切不好,直接用手撕更好。
4,我从来都是手撕的,力道、撕出来的形状都非常棒。用菜刀切出来的东西太整齐了反不好,比如手撕包菜。
5,啥叫厨房,就是炒菜用锅,煮饭用蒸笼,煨汤用砂锅。一个好的厨房就是应该各种能配置的工具都配置齐全了。
6,一个厨房搞那么多工具干嘛,我看就一个火堆,一个钢叉就可以了。


本帖精华所在。
20 楼 hejian1860 2008-03-18  
例子能把意思說清楚,這就夠了,明白之后根據實際情況應用,沒有必要追著喊例子不合適;謝謝樓主的闡述。
19 楼 fsj0101 2008-03-18  
wgfywin 写道
其实楼主只是在介绍菜刀的用法:以前都是用手撕的,后来用菜刀切,方便多了。
结果跟帖的人说
1,菜刀不能劈柴;
2,菜刀太锋利,搞不好把手切了。
3,有些菜用菜刀切不好,直接用手撕更好。
4,我从来都是手撕的,力道、撕出来的形状都非常棒。用菜刀切出来的东西太整齐了反不好,比如手撕包菜。
5,啥叫厨房,就是炒菜用锅,煮饭用蒸笼,煨汤用砂锅。一个好的厨房就是应该各种能配置的工具都配置齐全了。
6,一个厨房搞那么多工具干嘛,我看就一个火堆,一个钢叉就可以了。



你太强了!!
18 楼 ssuupv 2008-03-10  
设计模式,其实看书看例子,大家都觉得过于设计了,但是在实际应用中,能合理运用设计模式,后期维护可以说事半功倍效果.
17 楼 ssuupv 2008-03-10  
其实这个思想,真的很好.我看了很多公司代码,他们在一个方法里面有.三千多行有的更多也就是他把整个业务写在这个方法里面(在维护代码狂痛苦).如果运用上面方法,我们可以分折出若干小方法,这样可读性强很多,维护起来也是比较方便,还有这些小方法也许还能在其他重用.
16 楼 outh 2008-03-10  
这个例子有点过度设计的味道……
15 楼 ivaneve 2008-03-07  
仔细看了下。还是觉得方案1更好。无论从代码的易读性还是可维护性上来说!
14 楼 ardenliu 2008-02-29  
simple is the best.
13 楼 likehibernate 2008-02-29  
个人觉得应该就是把动作也抽象成接口,就像组件一样,要的时候拿一个来组合着用!
12 楼 yongyuan.jiang 2008-02-22  
不同的需求、环境,有不同的解决方案,不同的设计模式适用于解决不同的问题。

设计模式只是思想,在此不对这个例子作其他评论。
也不做极端的推论。

考虑的问题不同,要使用的模式也不同。
懂了这个是什么,要用的时候就可以了。
11 楼 jenlp520 2008-02-21  
111111
10 楼 jenlp520 2008-02-21  
其实我觉得比这更好的办法是用内部类来实现
只是可能会在代码的观赏性上没这个好
9 楼 jenlp520 2008-02-21  
java的io用的就是这个模式
 
只能说解决了java不能多继承的问题 但在执行顺序上不灵活
8 楼 ajoo 2008-02-21  
yongyuan.jiang 写道
呵呵,是吗。
当我从设计模式读到这文的时候,感觉非常开心,设计者把代码写灵活了。原来代码还能这么写。

方案1如果要修改,则需要修改Ticket的源代码。
方案1模拟了业务变更的流程。全部需要修改Ticket源代码。

方案2面对变更的需求,不用改Ticket,使用者自己按需求构造即可。
方案2如果要修改,不用修改源代码,添加一个自己的类(即修饰者)即可。


对呀,对呀。还要加上ResourceBundle:万一需求变化需要国际化的嘛;
还要注射PrintStream而不是直接System.out:万一需求变化要写到文件中的嘛;
还要加一个策略模式:万一需求变化不是写纯文本而是html甚至flash的嘛;
还要加一个observer模式:万一需求变化要响应不同的组件打印事件的嘛;
还要搞一个xml文件来组装所有组件的嘛;还要弄一个controller, view, model来分隔不同层次的逻辑的嘛;
还要用上aop:万一需求变化那啥那啥的嘛。。。

啥叫”架构师“?就是所有能叫得上名的模式你全给他整上。
7 楼 yongyuan.jiang 2008-02-21  
引用
细细看了一下Header类和Footer类中其实现方法中的步骤是不一样的,这顺序不还是不能改的吗? 望解答。


header顾名思义应该是头部。
footer顾名思义在尾部。

当然可以header + header + header达到改变顺序
footer + footer + footer.

你的意思是不可能出现:
header - footer - header -footer
这当然不能出现了。

6 楼 yongyuan.jiang 2008-02-21  
呵呵,是吗。
当我从设计模式读到这文的时候,感觉非常开心,设计者把代码写灵活了。原来代码还能这么写。

方案1如果要修改,则需要修改Ticket的源代码。
方案1模拟了业务变更的流程。全部需要修改Ticket源代码。

方案2面对变更的需求,不用改Ticket,使用者自己按需求构造即可。
方案2如果要修改,不用修改源代码,添加一个自己的类(即修饰者)即可。
5 楼 Uranus 2008-02-20  
xiaolin0105 写道
方案2的代码可读性,效率,可维护性都比不上方案1啊,呵呵。。。
方案1简直就是神来之笔,简单,易读,高效,利于维护。
其实lz这个例子可以用来作为使用design pattern的一个反例,就是不用什么都用design pattern,需要用才用,用比不用好才用,不要过度设计。如果可以1+1=2得来的东西,就不要通过1+2-4+2+1=2来得到。
不合算,不值得,是对资源(精力,时间)的浪费。
胡乱说两句。

我想楼主的意思应该是用最简单的方法来说明decorator模式,但是对于一上来二话不说先贴代码,然后总结下结束,让我有点摸不到头脑,decorator模式到底有趣到哪了,为什么要用这种模式。

PS:讲设计模式只要类图就可以了,关键是思想。
4 楼 xiaolin0105 2008-02-19  
方案2的代码可读性,效率,可维护性都比不上方案1啊,呵呵。。。
方案1简直就是神来之笔,简单,易读,高效,利于维护。
其实lz这个例子可以用来作为使用design pattern的一个反例,就是不用什么都用design pattern,需要用才用,用比不用好才用,不要过度设计。如果可以1+1=2得来的东西,就不要通过1+2-4+2+1=2来得到。
不合算,不值得,是对资源(精力,时间)的浪费。
胡乱说两句。
3 楼 coder1982 2008-02-19  
细细看了一下Header类和Footer类中其实现方法中的步骤是不一样的,这顺序不还是不能改的吗? 望解答。

相关推荐

    设计模式:可复用面向对象软件的基础.zip

    8. 装饰模式(Decorator):动态地给一个对象添加一些额外的职责。装饰者模式可以用来扩展功能,而无需修改原有代码。 9. 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。代理模式常用于远程...

    《设计模式:可复用面向对象软件的基础》英文版

    如适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Composite)、装饰者模式(Decorator)、外观模式(Facade)、享元模式(Flyweight)和代理模式(Proxy)等。 - **行为型模式**:关注于对象间的职责分配,...

    设计模式:可复用面向对象软件的基础--详细书签版

     本书结合设计实例从面向对象的设计中精选出23个设计模式,总结了面向对象设计中最有价值的经验,并且用简洁可复用的形式表达出来。本书分类描述了一组设计良好、表达清楚的软件设计模式,这些模式在实用环境下特别...

    《设计模式:可复用面向对象软件的基础》学习并理解 23 种设计模式

    - **装饰器模式**(Decorator):动态地给一个对象添加一些额外的责任。 - **外观模式**(Facade):为子系统中的一组接口提供一个一致的界面。 - **享元模式**(Flyweight):运用共享技术有效地支持大量细粒度...

    设计模式学习笔记大全

    以上就是压缩包中的设计模式学习笔记涉及到的主要内容。通过对这些模式的理解和应用,开发者可以更好地解决软件设计中的问题,提升软件的质量和可维护性。每种模式都有其适用场景,理解其背后的意图和应用场景是关键...

    设计模式学习笔记总结

    这里我们聚焦于C#语言中的设计模式学习笔记,涵盖了多种经典的设计模式,如合成模式、桥梁模式、装饰模式、享元模式、门面模式、命令模式、工厂方法、策略模式、代理模式以及状态模式。下面将对这些模式逐一进行详细...

    23种java设计模式.pdf

    结构模式是指在对象之间的关系和结构上使用的模式,包括 Flyweight(共享模式)、Bridge(桥模式)、Decorator(装饰模式)、Composite(组合模式)、Adapter(适配器模式)、Proxy(代理模式)、Facade(外观模式)...

    C#面向对象设计模式纵横谈(10):Decorator 装饰模式(结构型模式) (Level 300)

    在这个“C#面向对象设计模式纵横谈”系列的第十篇中,我们将深入探讨Decorator模式。 首先,让我们了解装饰模式的基本组件: 1. **Component(组件)**:这是被装饰的对象的接口。它可以是抽象类或接口,定义了...

    23种设计模式(C++).pdf

    - Decorator模式:动态地给一个对象添加一些额外的职责,就增加功能来说,Decorator模式比生成子类更为灵活。 - Composite模式:将对象组合成树形结构以表示“部分-整体”的层次结构,使得客户对单个对象和组合对象...

    设计模式之 Decorator模式和代码实现

    【Decorator模式】是一种设计模式,它允许在运行时动态地给对象添加新的责任或功能,而不必通过子类化的方式。在上述的奇幻RPG游戏中,Decorator模式被用来实现武器的锻造过程,尤其是武器镶嵌宝石的功能。这个过程...

    java设计模式之Builder&Decorator

    Java设计模式中的Builder模式和Decorator模式是两种重要的设计模式,它们在软件开发中起到优化代码结构、提高代码复用性和灵活性的作用。 1. 建造者模式(Builder) 建造者模式是一种创建型设计模式,它的主要目的...

    图解Java设计模式笔记总结word版本.rar

    本资料“图解Java设计模式笔记总结word版本”聚焦于通过图文并茂的方式,深入浅出地解析各种设计模式。以下是基于这个主题的详细知识点讲解: 1. **设计模式的分类** - **创建型模式**:如单例(Singleton)、工厂...

    设计模式可复用面向对象软件的基础 源码

    - 装饰模式(Decorator):动态地给对象添加一些额外的职责,提供了比继承更有弹性的扩展方式。 - 外观模式(Facade):为子系统提供一个统一的接口,简化其使用。 - 享元模式(Flyweight):通过共享技术有效地...

    C#设计模式之Decorator 装饰模式

    装饰模式(Decorator Pattern)是设计模式中的一种结构型模式,它在不改变原有对象的基础上,通过添加额外的职责来扩展对象的功能。在C#中,装饰模式尤其适用于那些需要动态地增加或减少对象功能的情况,避免了使用...

    设计模式之装饰模式(Decorator Pattern)

    装饰模式(Decorator Pattern)是一种结构型设计模式,它在不改变原有对象的基础上,通过包裹一个对象并为其添加新的行为或责任,实现对对象功能的扩展。这种模式在软件开发中非常常见,尤其当需要在运行时动态改变...

    JAVA设计模式chm文档

    设计模式之Decorator(油漆工) 设计模式之Bridge 设计模式之Flyweight(享元) 行为模式: 设计模式之Template 设计模式之Memento(备忘机制) 设计模式之Observer 设计模式之Chain of Responsibility(职责链) 设计模式之...

    设计模式之美—学习笔记

    在这个“设计模式之美”的学习笔记中,我们将探讨一些主要的设计模式,以及它们在实际开发中的应用。 首先,我们从创建型模式开始。这类模式主要用于对象的创建,如单例模式(Singleton)、工厂模式(Factory ...

    C++设计新思维:泛型编程与设计模式之应用

    2. 结构型模式:如适配器模式(Adapter)、装饰器模式(Decorator)、桥接模式(Bridge)等,用于组合对象或类,改善它们的结构。 3. 行为型模式:如策略模式(Strategy)、观察者模式(Observer)、访问者模式...

    台湾人写的设计模式笔记

    这份由台湾作者编写的笔记,结合Java语言,为读者提供了一种深入理解并应用设计模式的方式。以下是对这些设计模式的详细解释: 1. **创建型模式(Creational Patterns)** 创建型模式关注于对象的创建过程,它们帮助...

    [结构型模式] head first 设计模式之装饰者模式(decorator)

    装饰者模式(Decorator Pattern)是结构型设计模式之一,它允许在运行时向对象添加新的行为或职责,而无需修改对象的源代码。这个模式的名字来源于装饰艺术,它通过增加额外的装饰来增强一个物体的外观,同样地,...

Global site tag (gtag.js) - Google Analytics