设计模式之装饰者模式

设计模式之装饰着模式
  1. 简单例子说明装饰者模式

    1. 星巴克咖啡订单项目(咖啡管)

      1. 咖啡种类:Espresso(意大利浓咖啡)、shortBlack、LongBlack、Decaf

      2. 调料:Milk、Chicilate、Soy(豆浆)

      3. 要求在扩展新的咖啡时,具有良好的延展性、改动方便、维护方便

      4. 使用OO来计算不同种类咖啡的费用:用户可以点单品咖啡,也可以单品+调料组合

    2. 实施方案

      1. 方案一(不推荐)

        1. 类图

        2. 分析

          1. Drink是一个抽象类,表示饮料

          2. des就是对咖啡的描述,比如咖啡封顶名字,价格等等

          3. cost()就是计算费用,在Drink是一个抽象方法

          4. 单品咖啡继承了Drink

          5. Espress && Milk就是单品咖啡+调料。这种组合很多

        3. 缺点:

          1. 这样设计时,当我们增加一个新非咖啡种类或者调料时,类的数量机会倍增,就会出现类爆炸

      2. 方案二(比方案一好一些)

        1. 上面在方案一分析出,如果使用方案一会发生类爆炸,因此方案二进行了改进,将调料内置到Drink,这样就不会造成类的数量过多,从而提高项目的维护性

        2. 类图

        3. 分析

          1. 方案二可以控制类的数量,不至于造成很多的类

          2. 在增加或者删除调料种类时,代码的维护量还是很大

          3. 考虑到用户可以添加多份调料时,可以将hasXXX()返回一个int

          4. 考虑使用装饰者模模式

  2. 通过装饰者模式解决上面两种解决方案的不足、

    1. 装饰者模式定义

      1. 装饰者模式:动态的将新功能附加到对象上,在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则

      2. 这里提到的动态的将新功能附加到对象和ocp原则,在代码会会得以体现

    2. 装饰者模式原理

      1. 说明

      2. 实现图

      3. 代码实现

        //注意分包
        //编写Drink,这是一个比较重要的类
        public abstract class Drink{
           public String des;//对Drink的描述
           private float price = 0.0f;
           //增加get和set方法
           //计算 费用的抽象方法
           public abstract float cost();
        }
        //编写coffee类
        public class Coffee extends Drink{
           @Iverride
           public float cost(){
               super.getPrice();
          }
        }
        //编写具体的咖啡种类
        public class Espresso extends Coffee{
           public Espresso(){
               setDes("意大利浓咖啡");
               setPrice(6.0f);
          }
        }
        //其他咖啡参考Espresso来写就可以了

        //装饰者
        public class Decorator extend Drink{
           private Drink obj;
           public Decorator(Drink obj){
               this.obj =obj;
          }
           @Override
           public float cost(){
               return super.getPrice() + obj.cost();
          }
           
           @Override
          public String getDes(){
               //obj.getDes()输出被装饰者的信息
               return super.des + " "  + super.getPrice() + " && " +obj.getDes();
          }
        }

        //编写调味品的信息
        // 巧克力
        public class Chocolate extends Decorator{
           public Chocolate(Drink obj){
               super(obj);
               setDes("巧克力");
               //设置当前调味品的价格
               setprice(3.0f);
          }
        }

        //其他的调味品参考巧克力


        //下订单
        public class CoffeeBar{
           public static void main(String[] args){
               //下订单:2分巧克力+一份牛奶的LongBlack,补全调味品
               //步骤1:点一份被装饰者
               Drink order = new LongBalck();
               System.out.println("费用1 = "+order.cost());
               
               //步骤2:加入一份牛奶
              order = new Milk(order);
               //步骤3:加入一份巧克力
               order = new Chocolate(order);
               //步骤4:在加入一份巧乐力
               order = new Chocolate(order);
               System.out.println("描述 = "+order.getDes());
               System.out.println("费用 = "+order.cost());
               
          }
        }

         

      4. 装饰者模式在JDK应用中的源码

        1. java的I/o结构,FilterInputStream就是一个装饰者

        2. 代码

        3.  

原文地址:https://www.cnblogs.com/juddy/p/14995112.html