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

    装饰者模式

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

    装饰者模式原理

    1. 装饰者模式就像打包一个快递
      主体:
      比如:陶瓷、衣服(Component)//被装饰者包装:
      比如:报纸填充、塑料泡沫、纸板、木板(Decorator)
    2. Component 主体
    3. ConcreteComponent 和Decorator
      ConcreteComponent:具体的主体
    4. Decorator:装饰者

    在如图的Component与ConcreteComponent之间,如果ConcreteComponent类很多,还可以设计一个缓冲层,将共有的部分提取出来,抽象成一个类。

    image-20200729215632821

    装饰者模式咖啡订单项目应用实例

    1. 咖啡种类/单品咖啡: Espresso(意 大利浓咖啡)、ShortBlack、 LongBlack(美 式咖啡)、Decaf( 无因咖啡)
    2. 调料: Milk、 Soy( 豆浆)、Chocolate
    3. 要求在扩展新的咖啡种类时,具有良好的扩展性、改动方便、维护方便
    4. 使用OO的来计算不同种类咖啡的费用:客户可以点单品咖啡,也可以单品咖啡+调料组合。
    //具体的Decorator, 这里就是调味品
    public class Chocolate extends Decorator {
    
       public Chocolate(Drink obj) {
          super(obj);
          setDes(" 巧克力 ");
          setPrice(3.0f); // 调味品 的价格
       }
    
    }
    
    public class Coffee  extends Drink {
    
       @Override
       public float cost() {
          // TODO Auto-generated method stub
          return super.getPrice();
       }
    
       
    }
    
    public class CoffeeBar {
    
       public static void main(String[] args) {
          // TODO Auto-generated method stub
          // 装饰者模式下的订单:2份巧克力+一份牛奶的LongBlack
    
          // 1. 点一份 LongBlack
          Drink order = new LongBlack();
          System.out.println("费用1=" + order.cost());
          System.out.println("描述=" + order.getDes());
    
          // 2. order 加入一份牛奶
          order = new Milk(order);
    
          System.out.println("order 加入一份牛奶 费用 =" + order.cost());
          System.out.println("order 加入一份牛奶 描述 = " + order.getDes());
    
          // 3. order 加入一份巧克力
    
          order = new Chocolate(order);
    
          System.out.println("order 加入一份牛奶 加入一份巧克力  费用 =" + order.cost());
          System.out.println("order 加入一份牛奶 加入一份巧克力 描述 = " + order.getDes());
    
          // 3. order 加入一份巧克力
    
          order = new Chocolate(order);
    
          System.out.println("order 加入一份牛奶 加入2份巧克力   费用 =" + order.cost());
          System.out.println("order 加入一份牛奶 加入2份巧克力 描述 = " + order.getDes());
       
          System.out.println("===========================");
          
          Drink order2 = new DeCaf();
          
          System.out.println("order2 无因咖啡  费用 =" + order2.cost());
          System.out.println("order2 无因咖啡 描述 = " + order2.getDes());
          
          order2 = new Milk(order2);
          
          System.out.println("order2 无因咖啡 加入一份牛奶  费用 =" + order2.cost());
          System.out.println("order2 无因咖啡 加入一份牛奶 描述 = " + order2.getDes());
    
       
       }
    
    }
    
    public class Coffee  extends Drink {
    
       @Override
       public float cost() {
          // TODO Auto-generated method stub
          return super.getPrice();
       }
    
       
    }
    
    public class Decorator extends Drink {
       private Drink obj;
       
       public Decorator(Drink obj) { //组合
          // TODO Auto-generated constructor stub
          this.obj = obj;
       }
       
       @Override
       public float cost() {
          // TODO Auto-generated method stub
          // getPrice 自己价格
          return super.getPrice() + obj.cost();
       }
       
       @Override
       public String getDes() {
          // TODO Auto-generated method stub
          // obj.getDes() 输出被装饰者的信息
          return des + " " + getPrice() + " && " + obj.getDes();
       }
       
       
    
    }
    
    public abstract class Drink {
    
       public String des; // 描述
       private float price = 0.0f;
       public String getDes() {
          return des;
       }
       public void setDes(String des) {
          this.des = des;
       }
       public float getPrice() {
          return price;
       }
       public void setPrice(float price) {
          this.price = price;
       }
       
       //计算费用的抽象方法
       //子类来实现
       public abstract float cost();
       
    }
    
    public class Espresso extends Coffee {
       
       public Espresso() {
          setDes(" 意大利咖啡 ");
          setPrice(6.0f);
       }
    }
    
    public class LongBlack extends Coffee {
    
       public LongBlack() {
          setDes(" longblack ");
          setPrice(5.0f);
       }
    }
    
    public class Milk extends Decorator {
    
       public Milk(Drink obj) {
          super(obj);
          // TODO Auto-generated constructor stub
          setDes(" 牛奶 ");
          setPrice(2.0f); 
       }
    
    }
    
    public class ShortBlack extends Coffee{
       
       public ShortBlack() {
          setDes(" shortblack ");
          setPrice(4.0f);
       }
    }
    
    public class Soy extends Decorator{
    
       public Soy(Drink obj) {
          super(obj);
          // TODO Auto-generated constructor stub
          setDes(" 豆浆  ");
          setPrice(1.5f);
       }
    
    }
    
  • 相关阅读:
    APP性能测试中的几个重要概念
    linux初学体会
    Centos 关闭指定端口的进程
    【初学Python】01-第一个小说爬虫
    SQLsever存储过程分页查询
    记MVC学习过程中一次传参到View时遇到的错误
    未能加载文件或程序集“System.Web.Mvc, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项
    Android Studio导包无效,全部报红
    记一次使用SimpleDateFormat 格式化时间时遇到的问题
    Spring-Boot中Tomcat端口修改
  • 原文地址:https://www.cnblogs.com/junlinsky/p/14067838.html
Copyright © 2011-2022 走看看