HeadFirst设计模式_读书笔记_003_装饰者模式

1.问题的引入:

   有时候我们需要动态地扩展对象的功能。比如现在给快餐店编写一菜单程序。主食和菜品可以互相搭配,我们要怎么确立餐厅需要的各种菜单类呢?

  首先我们尝试下类的继承能不能解决问题:

  主食和菜是两个接口,任何一个菜单里面都应该搭配主食和菜,那我们就把所有的搭配都定义成类。菜单是一个实现了这两个接口的超类,任何一种特定的主食+菜式搭配都可以定义一个新类,继承菜单这个超类就可以了。

  

  这样写肯定是会被老大骂的,主食和菜式特别多的时候,类的数量级也特别大。维护量太大。三种主食,20种菜的话就是六十个类。哪天新加一种主食,开发得写20个类,还是在一个主食只能搭配一种菜式这种最简单的情况下,不利于扩展,pass掉。
 

  其次我们再来看看组合能不能解决问题:

  毕竟菜单是由主食和各色菜式搭配的么?那我们的菜单类应该是这样的:

   
   这种组合的设计至少没有类的泛滥,老大不会马上骂你的。现在我们来看看还有什么问题? 首先,Order里面定义了三个菜式的属性,那么就意味着一个用户最多只能吃三样菜。多了我们就不支持了,可能大多情况下,我们吃快餐只要一份菜,那么另外两个为空,在计算价格和获取菜式的描述的方法里面,我们还是要考虑可能为空的值。说白了,能解决问题,但是代码还是不够简洁。每次都要检查非空,也的确不是很合理。

  那么有没有更加智能的解决方法呢?下面我们就引出装饰者模式。

2. 装饰者模式:

    动态给一个对象添加一些额外的职责。

    就上面的问题,对象就是主食,额外的职责就是那些各式各样的菜色。下面我们来看下类图:

    

     在上面的类图我们可以看到,被装饰的主题即各种主食和所谓的装饰者(各色菜式)是同源的,他们都实现了同一个接口,当然你也可以设计成一个抽象类。我们前面讲了,不是不用继承么? 这里的继承和前面的继承是有本质的区别的。前面是为了继承某一个功能就继承那个类,所以最后类泛滥了。但是在观察者模式里面,继承是为了方便装饰。你是一个主食,我装饰你之后,就变成了主食加某种菜式。但是不需要把这种装饰的组合维护成一种类。所以在装饰者模式里面,不会类泛滥。因为主食和菜式解耦了,所以动态添加各种菜式也变成了可能。                 

    3.代码实现:

 

 



  现在在来看下测试代码和执行结果:

  

  执行结果:

  

 

 看看测试代码,我们先用白菜装饰米饭,相当于是一个米饭配白菜的菜单,后面又用萝卜继续装饰,就是白菜萝卜加米饭的菜单。现在明白了,为什么装饰者和被装饰者要是同源了的吧?动态装饰,这样设计,如果一个人想吃一百种菜我们也能解决。哈哈~~~ 前提的是他的胃容量足够大。

 
 
 

 



 

  

   
 

猜你喜欢

转载自afra-liu.iteye.com/blog/2361337
今日推荐