• 设计模式之装饰者模式


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

  • 相关阅读:
    Java 学习总结(一)
    每日学习心得:SharePoint 为列表中的文件夹添加子项(文件夹)、新增指定内容类型的子项、查询列表中指定的文件夹下的内容
    每日学习心得:SharePoint 2013 自定义列表项添加Callout菜单项、文档关注、SharePoint服务端对象模型查询
    HighCharts使用心得
    ECharts使用心得总结(二)
    每日学习心得:Js基本数据类型常用方法扩展
    每日学习心得:$.extend()方法和(function($){...})(jQuery)详解
    Mustache 使用心得总结
    Extjs editor 设置默认值
    Ext this.getView(...).saveDocumentAs is not a function
  • 原文地址:https://www.cnblogs.com/juddy/p/14995112.html
Copyright © 2020-2023  润新知