head frist 设计模式学习之 装饰者模式 您所在的位置:网站首页 jokerstudio head frist 设计模式学习之 装饰者模式

head frist 设计模式学习之 装饰者模式

2023-03-20 15:15| 来源: 网络整理| 查看: 265

前情提要:http://blog.csdn.net/baidu_30889437/article/details/50917814   JVM:"上次给我招的工人不错啊!" oo程序员:"..........." JVM:"现在来我开的博物馆生意越来越好了,原来"舞台剧"的方式已经不能满足顾客的需求了" oo程序员:"..........." JVM:"我决定要换一种运营模式,把每个演播厅都租出去,让那些想表演节目的对象们来租演播厅和相关器械,这样我就能坐地收钱了!" oo程序员:"..........." JVM:"合伙干吧?怎么样?你三我七!" oo程序员:"..........." JVM:"四六?" oo程序员:"成交!先说说需求。" JVM:"首先有不同类型的演播厅和不同的装饰品/器械,每种物品都要付一定的租金,你要做的就是一件事,把总租金(演播厅+饰品/器械)算出来。" oo程序员:"把价格表给我!" 卡通演播厅(CartoonStudio)     100 小丑演播厅(JokerStudio) 150 超级演播厅(SuperStudio) 300 。。。。。。 气球(Balloon)                 10  灯光(Lamplight) 25 麦克风(Microphone) 20 。。。。 最后还写下了这个: public abstract class Anything_ex {   String description=" ";  public String getDescription()  {   return description;     }  public abstract int cost(); } 仔细一想也对,无论是演播厅还是装饰品,都需要描述(description)和cost(价格),写一个共同的父类无可厚非。 接着写下你设计的第一个类: class CartoonandBalloon extends Anything_ex {  ....  public int cost()  {  return 100+10;  } }   //带气球的卡通演播厅 第二个: class CartoonandLamplight extends Anything_ex { ...  public int cost()  {  return 100+25;  } }  //带灯光的卡通演播厅 第三个: 。。。。。 没有第三个了!这样写下去可是无穷无尽的!没办法,换个思路。 在演播厅里,无论什么装饰品都有可能出现,可以把演播厅+饰品看成一个整体,通过饰品相应的has和set来控制饰品,这样的话,设计出来的类如下: class CartoonStudio extends Anything_ex {        private  boolean Balloon=false;        .... //省略其他变量,这里只以气球为例        public boolean hasBalloon()        {                return Ballon;        }         public void setBallon()        {                Balloon=true;        }        .......//省略其他has/set方法        public int cost()        {                int cost=100; //卡通演播厅的初始价格为100         if(hasBalloon)         {         cost+=10;         }         else if(hasXXX).....//省略类推下来的代码                 return cost;        }   } 这个看起来好多了,不用写大爆炸数量的类,虽然类写起来又臭(无数的has/set)又长(的确很长)。。。。。 。。。。。。。 但是有没有更好的方案? 答案当然是有的,不过我们必须先明确一下,上述设计的缺点。 1.臭 2.长 画外:玩笑,23333 3.当饰品的租金改变的时候,必须修改所有演播厅的代码(cost部分),我们当然不想这样,我们想尽可能的少修改代码(松耦合)。 4.没有面对超类/接口编程。 5.没有将变化的部分独立开。 6.组合可能是更好的解决方案。 下面让我们看看。装饰者模式是如何解决上面问题的。 装饰者模式:动态的将责任加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。 首先,我们先将演播厅和他的装饰者们分开,让装饰者继承另一个类: public abstract class Decorater_ex extends Anyting_ex {              public abstract String getDescription();              } 让装饰者子类重新实现getDescription()即可。 现在我们的思路是:用装饰者装饰演播厅,例如,一个带麦克风和气球的卡通演播厅,就先让气球装饰卡通演播厅,再让麦克风装饰“带气球的卡通演播厅” 先让我们分别实现这3个类: 卡通演播厅: class CortoonStudio extends Anything_ex {                      public CortoonStudio()           {               description="CortonStudio";           }           publuc int cost()           {             return 100;           } } 麦克风: class Microphone extends Decorater_ex {         private Anything_ex studio;           public Microphone(Anything_ex studio )           {            this.studio=studio;           }           public String getDescription()           {           return studio.getDescription()+",Microphone";           }           public int cost()           {           return studio.cost()+20;           } } 气球:  class Balloon extends Decorater_ex {         private Anything_ex studio;           public Balloon(Anything_ex studio )           {            this.studio=studio;           }           public String getDescription()           {           return studio.getDescription()+",Balloon";           }           public int cost()           {           return studio.cost()+10 ;           } } 代码:     Anything_ex CortoonStudio =new CortoonStudio();    //一个卡通演播厅对象    CortoonStudio=new Microphone(CortoonStudio); //拿麦克风装饰    CortoonStudio=new Balloon(CortoonStudio);  //拿气球装饰    System.out.println(CortoonStudio.getDescription()+"="+CortoonStudio.cost()); 输出结果:  CortonStudio,Microphone,Balloon=130  结果是正确的。  这样写很好的解决了上面的问题。  1.运用组合进行扩展,使当价格改变的时候,只需要修改本身的代码。  2.面对超类/接口编程,使饰品增加种类的时候,并不需要修改被装饰者的代码。  3.开放——关闭原则 :代码应该对扩展开放,对修改关闭。  缺陷:  1.子类繁多,影响理解代码(java I/O就是装饰者模式哦。。。)。  2.无法应用于需要具体类的场景。

 这篇文章到此差不多结束了,作者功力尚浅,文章如有不正之处请读者指出,海涵。

本文为博主原创,首发自码农网:http://www.codeceo.com/article/java-decorator-pattern.html



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有