2007-12-05
设计模式笔记:好玩的Decorator模式
关键字: 好玩的decorator模式
《设计模式》对Decorator的描述:动态给一个对象添加一些额外职责。就添加功能来说,Decorator模式比生成子类更灵活。
Decorator让我感觉设计者非常聪明,这是个好有趣聪慧的模式,马上看例子:
1.不使用Decorator模式的设计:
a.需求:打印正文
b.需求改变:打印正文前,先打印Header
c.需求再度改变:正文后打印Footer
2.使用Decorator后的设计:
于是,无论添加多少个功能,每个Decorator都之关心自己的功能,我们能任意重排Decorator的顺序,无需改变任何代码。
在java io中用到了Decorator模式。
Decorator让我感觉设计者非常聪明,这是个好有趣聪慧的模式,马上看例子:
1.不使用Decorator模式的设计:
a.需求:打印正文
java 代码
- public class Ticket{
- public void prtTicket(){
- System.out.println("Sales Ticket");
- }
- }
b.需求改变:打印正文前,先打印Header
java 代码
- public class Ticket{
- public void prtTicket(){
- System.out.println("Header");
- System.out.println("Sales Ticket");
- }
- }
c.需求再度改变:正文后打印Footer
java 代码
- public class Ticket{
- public void prtTicket(){
- System.out.println("Header");
- System.out.println("Sales Ticket");
- System.out.println("Footer");
- }
- }
2.使用Decorator后的设计:
java 代码
- abstract public class Component{
- abstract public void prtTicket();
- }
- abstract public class TicketDecorator extend Component {
- private Component myTrailer;
- public TicketDecorator(Component comp){
- myTrailer = comp;
- }
- public void callTrailer(){
- if(myTrailer != null)
- myTrailer.prtTicket();
- }
- }
- public class SaleTicket extend Component{
- public void prtTicket(){
- System.out.println("Sale Ticket");
- }
- }
- public class Header extend TicketDecorator{
- public Header(Component comp){
- super(comp);
- }
- public void prtTicket(){
- System.out.println("Header");
- super.callTrailer();
- }
- }
- public class Footer extend TicketDecorator{
- public Footer (Component comp){
- super(comp);
- }
- public void prtTicket(){
- super.callTrailer();
- System.out.println("Footer");
- }
- }
- public class Test{
- public static void main(String args[]){
- Component c = new Header(new Footer(new SaleTicket()));
- c.prtTicket();
- }
- }
于是,无论添加多少个功能,每个Decorator都之关心自己的功能,我们能任意重排Decorator的顺序,无需改变任何代码。
在java io中用到了Decorator模式。
评论
halfmile
2008-03-21
经典,经典,简直经典到可以被抽象出来作为描述论坛讨论贴的设计模式
wgfywin 写道
其实楼主只是在介绍菜刀的用法:以前都是用手撕的,后来用菜刀切,方便多了。
结果跟帖的人说
1,菜刀不能劈柴;
2,菜刀太锋利,搞不好把手切了。
3,有些菜用菜刀切不好,直接用手撕更好。
4,我从来都是手撕的,力道、撕出来的形状都非常棒。用菜刀切出来的东西太整齐了反不好,比如手撕包菜。
5,啥叫厨房,就是炒菜用锅,煮饭用蒸笼,煨汤用砂锅。一个好的厨房就是应该各种能配置的工具都配置齐全了。
6,一个厨房搞那么多工具干嘛,我看就一个火堆,一个钢叉就可以了。
结果跟帖的人说
1,菜刀不能劈柴;
2,菜刀太锋利,搞不好把手切了。
3,有些菜用菜刀切不好,直接用手撕更好。
4,我从来都是手撕的,力道、撕出来的形状都非常棒。用菜刀切出来的东西太整齐了反不好,比如手撕包菜。
5,啥叫厨房,就是炒菜用锅,煮饭用蒸笼,煨汤用砂锅。一个好的厨房就是应该各种能配置的工具都配置齐全了。
6,一个厨房搞那么多工具干嘛,我看就一个火堆,一个钢叉就可以了。
Nighthaven
2008-03-18
wgfywin 写道
其实楼主只是在介绍菜刀的用法:以前都是用手撕的,后来用菜刀切,方便多了。
结果跟帖的人说
1,菜刀不能劈柴;
2,菜刀太锋利,搞不好把手切了。
3,有些菜用菜刀切不好,直接用手撕更好。
4,我从来都是手撕的,力道、撕出来的形状都非常棒。用菜刀切出来的东西太整齐了反不好,比如手撕包菜。
5,啥叫厨房,就是炒菜用锅,煮饭用蒸笼,煨汤用砂锅。一个好的厨房就是应该各种能配置的工具都配置齐全了。
6,一个厨房搞那么多工具干嘛,我看就一个火堆,一个钢叉就可以了。
结果跟帖的人说
1,菜刀不能劈柴;
2,菜刀太锋利,搞不好把手切了。
3,有些菜用菜刀切不好,直接用手撕更好。
4,我从来都是手撕的,力道、撕出来的形状都非常棒。用菜刀切出来的东西太整齐了反不好,比如手撕包菜。
5,啥叫厨房,就是炒菜用锅,煮饭用蒸笼,煨汤用砂锅。一个好的厨房就是应该各种能配置的工具都配置齐全了。
6,一个厨房搞那么多工具干嘛,我看就一个火堆,一个钢叉就可以了。
本帖精华所在。
hejian1860
2008-03-18
例子能把意思說清楚,這就夠了,明白之后根據實際情況應用,沒有必要追著喊例子不合適;謝謝樓主的闡述。
fsj0101
2008-03-18
wgfywin 写道
其实楼主只是在介绍菜刀的用法:以前都是用手撕的,后来用菜刀切,方便多了。
结果跟帖的人说
1,菜刀不能劈柴;
2,菜刀太锋利,搞不好把手切了。
3,有些菜用菜刀切不好,直接用手撕更好。
4,我从来都是手撕的,力道、撕出来的形状都非常棒。用菜刀切出来的东西太整齐了反不好,比如手撕包菜。
5,啥叫厨房,就是炒菜用锅,煮饭用蒸笼,煨汤用砂锅。一个好的厨房就是应该各种能配置的工具都配置齐全了。
6,一个厨房搞那么多工具干嘛,我看就一个火堆,一个钢叉就可以了。
结果跟帖的人说
1,菜刀不能劈柴;
2,菜刀太锋利,搞不好把手切了。
3,有些菜用菜刀切不好,直接用手撕更好。
4,我从来都是手撕的,力道、撕出来的形状都非常棒。用菜刀切出来的东西太整齐了反不好,比如手撕包菜。
5,啥叫厨房,就是炒菜用锅,煮饭用蒸笼,煨汤用砂锅。一个好的厨房就是应该各种能配置的工具都配置齐全了。
6,一个厨房搞那么多工具干嘛,我看就一个火堆,一个钢叉就可以了。
你太强了!!
ssuupv
2008-03-10
设计模式,其实看书看例子,大家都觉得过于设计了,但是在实际应用中,能合理运用设计模式,后期维护可以说事半功倍效果.
ssuupv
2008-03-10
其实这个思想,真的很好.我看了很多公司代码,他们在一个方法里面有.三千多行有的更多也就是他把整个业务写在这个方法里面(在维护代码狂痛苦).如果运用上面方法,我们可以分折出若干小方法,这样可读性强很多,维护起来也是比较方便,还有这些小方法也许还能在其他重用.
outh
2008-03-10
这个例子有点过度设计的味道……
wgfywin
2008-03-08
其实楼主只是在介绍菜刀的用法:以前都是用手撕的,后来用菜刀切,方便多了。
结果跟帖的人说
1,菜刀不能劈柴;
2,菜刀太锋利,搞不好把手切了。
3,有些菜用菜刀切不好,直接用手撕更好。
4,我从来都是手撕的,力道、撕出来的形状都非常棒。用菜刀切出来的东西太整齐了反不好,比如手撕包菜。
5,啥叫厨房,就是炒菜用锅,煮饭用蒸笼,煨汤用砂锅。一个好的厨房就是应该各种能配置的工具都配置齐全了。
6,一个厨房搞那么多工具干嘛,我看就一个火堆,一个钢叉就可以了。
结果跟帖的人说
1,菜刀不能劈柴;
2,菜刀太锋利,搞不好把手切了。
3,有些菜用菜刀切不好,直接用手撕更好。
4,我从来都是手撕的,力道、撕出来的形状都非常棒。用菜刀切出来的东西太整齐了反不好,比如手撕包菜。
5,啥叫厨房,就是炒菜用锅,煮饭用蒸笼,煨汤用砂锅。一个好的厨房就是应该各种能配置的工具都配置齐全了。
6,一个厨房搞那么多工具干嘛,我看就一个火堆,一个钢叉就可以了。
ivaneve
2008-03-07
仔细看了下。还是觉得方案1更好。无论从代码的易读性还是可维护性上来说!
ardenliu
2008-02-29
simple is the best.
likehibernate
2008-02-29
个人觉得应该就是把动作也抽象成接口,就像组件一样,要的时候拿一个来组合着用!
yongyuan.jiang
2008-02-22
不同的需求、环境,有不同的解决方案,不同的设计模式适用于解决不同的问题。
设计模式只是思想,在此不对这个例子作其他评论。
也不做极端的推论。
考虑的问题不同,要使用的模式也不同。
懂了这个是什么,要用的时候就可以了。
设计模式只是思想,在此不对这个例子作其他评论。
也不做极端的推论。
考虑的问题不同,要使用的模式也不同。
懂了这个是什么,要用的时候就可以了。
jenlp520
2008-02-21
其实我觉得比这更好的办法是用内部类来实现
只是可能会在代码的观赏性上没这个好
只是可能会在代码的观赏性上没这个好
jenlp520
2008-02-21
java的io用的就是这个模式
只能说解决了java不能多继承的问题 但在执行顺序上不灵活
只能说解决了java不能多继承的问题 但在执行顺序上不灵活
ajoo
2008-02-21
yongyuan.jiang 写道
呵呵,是吗。
当我从设计模式读到这文的时候,感觉非常开心,设计者把代码写灵活了。原来代码还能这么写。
方案1如果要修改,则需要修改Ticket的源代码。
方案1模拟了业务变更的流程。全部需要修改Ticket源代码。
方案2面对变更的需求,不用改Ticket,使用者自己按需求构造即可。
方案2如果要修改,不用修改源代码,添加一个自己的类(即修饰者)即可。
当我从设计模式读到这文的时候,感觉非常开心,设计者把代码写灵活了。原来代码还能这么写。
方案1如果要修改,则需要修改Ticket的源代码。
方案1模拟了业务变更的流程。全部需要修改Ticket源代码。
方案2面对变更的需求,不用改Ticket,使用者自己按需求构造即可。
方案2如果要修改,不用修改源代码,添加一个自己的类(即修饰者)即可。
对呀,对呀。还要加上ResourceBundle:万一需求变化需要国际化的嘛;
还要注射PrintStream而不是直接System.out:万一需求变化要写到文件中的嘛;
还要加一个策略模式:万一需求变化不是写纯文本而是html甚至flash的嘛;
还要加一个observer模式:万一需求变化要响应不同的组件打印事件的嘛;
还要搞一个xml文件来组装所有组件的嘛;还要弄一个controller, view, model来分隔不同层次的逻辑的嘛;
还要用上aop:万一需求变化那啥那啥的嘛。。。
啥叫”架构师“?就是所有能叫得上名的模式你全给他整上。
yongyuan.jiang
2008-02-21
引用
细细看了一下Header类和Footer类中其实现方法中的步骤是不一样的,这顺序不还是不能改的吗? 望解答。
header顾名思义应该是头部。
footer顾名思义在尾部。
当然可以header + header + header达到改变顺序
footer + footer + footer.
你的意思是不可能出现:
header - footer - header -footer
这当然不能出现了。
yongyuan.jiang
2008-02-21
呵呵,是吗。
当我从设计模式读到这文的时候,感觉非常开心,设计者把代码写灵活了。原来代码还能这么写。
方案1如果要修改,则需要修改Ticket的源代码。
方案1模拟了业务变更的流程。全部需要修改Ticket源代码。
方案2面对变更的需求,不用改Ticket,使用者自己按需求构造即可。
方案2如果要修改,不用修改源代码,添加一个自己的类(即修饰者)即可。
当我从设计模式读到这文的时候,感觉非常开心,设计者把代码写灵活了。原来代码还能这么写。
方案1如果要修改,则需要修改Ticket的源代码。
方案1模拟了业务变更的流程。全部需要修改Ticket源代码。
方案2面对变更的需求,不用改Ticket,使用者自己按需求构造即可。
方案2如果要修改,不用修改源代码,添加一个自己的类(即修饰者)即可。
Uranus
2008-02-20
xiaolin0105 写道
方案2的代码可读性,效率,可维护性都比不上方案1啊,呵呵。。。
方案1简直就是神来之笔,简单,易读,高效,利于维护。
其实lz这个例子可以用来作为使用design pattern的一个反例,就是不用什么都用design pattern,需要用才用,用比不用好才用,不要过度设计。如果可以1+1=2得来的东西,就不要通过1+2-4+2+1=2来得到。
不合算,不值得,是对资源(精力,时间)的浪费。
胡乱说两句。
方案1简直就是神来之笔,简单,易读,高效,利于维护。
其实lz这个例子可以用来作为使用design pattern的一个反例,就是不用什么都用design pattern,需要用才用,用比不用好才用,不要过度设计。如果可以1+1=2得来的东西,就不要通过1+2-4+2+1=2来得到。
不合算,不值得,是对资源(精力,时间)的浪费。
胡乱说两句。
我想楼主的意思应该是用最简单的方法来说明decorator模式,但是对于一上来二话不说先贴代码,然后总结下结束,让我有点摸不到头脑,decorator模式到底有趣到哪了,为什么要用这种模式。
PS:讲设计模式只要类图就可以了,关键是思想。
xiaolin0105
2008-02-19
方案2的代码可读性,效率,可维护性都比不上方案1啊,呵呵。。。
方案1简直就是神来之笔,简单,易读,高效,利于维护。
其实lz这个例子可以用来作为使用design pattern的一个反例,就是不用什么都用design pattern,需要用才用,用比不用好才用,不要过度设计。如果可以1+1=2得来的东西,就不要通过1+2-4+2+1=2来得到。
不合算,不值得,是对资源(精力,时间)的浪费。
胡乱说两句。
方案1简直就是神来之笔,简单,易读,高效,利于维护。
其实lz这个例子可以用来作为使用design pattern的一个反例,就是不用什么都用design pattern,需要用才用,用比不用好才用,不要过度设计。如果可以1+1=2得来的东西,就不要通过1+2-4+2+1=2来得到。
不合算,不值得,是对资源(精力,时间)的浪费。
胡乱说两句。
coder1982
2008-02-19
细细看了一下Header类和Footer类中其实现方法中的步骤是不一样的,这顺序不还是不能改的吗? 望解答。
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 10758 次
- 性别:

- 来自: 广州

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
gwt spring 完美整合
gwt前端定义一个异常类 public class ApplicationExc ...
-- by yongyuan.jiang -
gwt spring 完美整合
(gwt+spring)我想用aop拦截来判断session超时,但是我怎样才能 ...
-- by angeltping -
GWT HTML Template :模板 ...
hehe,HTMLTemplatePanel增强功能,gwt类直接获得模板页面对 ...
-- by yongyuan.jiang -
Gwt 服务端使用hiberante ...
能说说都有哪些问题?为什么产生?如何解决? 正打算在一个GWT项目的服务器端使用 ...
-- by abo -
gwt spring 完美整合
博主是javaeye上的gwt第一高人,特别希望博主可以就如何用gwt开发一个伸 ...
-- by abo






评论排行榜