装饰者模式的由来

来源:互联网 发布:招商软件下载 编辑:程序博客网 时间:2024/06/02 14:43


举个例子来说:星巴克咖啡订单管理系统

如下图:

           

Beverage是所有饮料的基类;cost()是抽象方法,所有子类都需要定义它们自己的cost()实现来返回特定饮料的价钱

除了咖啡以外,星巴克还提供丰富的调味品,比如:炼乳、巧克力、砂糖、牛奶等,而且这些调味品也是要单独按份收费的,所以调味品也是订单系统中重要的一部分。

于是,考虑到调味品的管理,又有了下面这样的类结构:


           


这样的结构肯定是有问题,因为以后随便增加一种调味品,继承于Beverage的子类还会 翻倍!

于是又有了另一种方案


               


首先在基类里增加了表示是否包含特定调味品的布尔变量,如milk, soy等,然后提供了一些has(get)和set方法来设置这些布尔值;其次在Beverage类里实现cost()方法来计算调味品的价钱。所有咖啡子类将仍然覆盖cost()方法,只是这次它们需要同时调用基类的cost()方法,以便获得咖啡加上调味品后的总价。

下面我们再来增加子类

             


基类的cost()方法将计算所有调味品的价钱(当然是只包括布尔值为true的调味品),子类里的cost()方法将扩展其功能,以包含特定类型饮料的价钱。

按照上图来说,不同中的咖啡的价格是经常变动的,那么在实现cost()时即可重写,但是如果我想点一杯脱咖啡因咖啡(Decaf)外加三份炼乳和一份砂糖呢?这样就很难实现,因为布尔值的改变只会记住我是否加过某种调味品,不会记加过几次

下面根据我们学的装饰者模式来设计:


          

这样做的好处是,咖啡单独的还是咖啡,我将调味品都继承装饰类,咖啡和调味品可以任意组合。具体类和装饰类完全的分离,实现了松耦合。



原创粉丝点击