zoukankan      html  css  js  c++  java
  • 设计模式之装饰者模式

    设计模式之装饰着模式
    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.  

  • 相关阅读:
    flume+kafka+storm打通过程
    kafka入门
    hive执行更新和删除操作
    redis存储对象与对象序列化详解
    语音常识--语音信号的数字模型
    声源测向: TDOA-GCC-PATH方法
    【面试】如何比较一个类型【模板使用】【sizeof用法】
    【概括】C++11/14特性
    【面试】编译器为我们实现了几个类成员函数?(c++)
    语音信号处理常识【摘抄|自用】
  • 原文地址:https://www.cnblogs.com/juddy/p/14995112.html
Copyright © 2011-2022 走看看