设计模式之装饰者模式

160 阅读2分钟

一、概述

  • 装饰者模式:动态地将新功能附加到对象上。在对象功能拓展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)
  • 装饰者模式就像打包一个快递,主体是Component;包装是Decorator;ConcreteComponent是具体的主体
  • 感觉这种方法,很像代理模式,只是这是静态的操作,局限性比较大

二、装饰者模式解决咖啡订单问题

在这里插入图片描述

  • 设置一个抽象基类Drink,包含该单品的价格price及描述desc属性。设置一个抽象方法,cost()
public abstract class Drink {
  private String desc;
  private double price;
  public Drink() {
  }
  public Drink(String desc, double price) {
    this.desc = desc;
    this.price = price;
  }
  public String getDesc() {
    return desc;
  }
  public void setDesc(String desc) {
    this.desc = desc;
  }
  public double getPrice() {
    return price;
  }
  public void setPrice(double price) {
    this.price = price;
  }
  public abstract double cost();
  public abstract String getDescription();
}
  • 抽象基类Coffee继承Drinkcost()表示当前饮品的价格,就是当前类的price属性,即啥都没加;getDesccription()为描述整个饮品的组合及价格,目前只有单品饮品及价格
public abstract class Coffee extends Drink {
  public Coffee() {
  }
  public Coffee(String desc, double price) {
    super(desc, price);
  }
  @Override
  public double cost() {
    return super.getPrice();
  }
  @Override
  public String getDescription() {
    return super.getDesc() + " " + super.getPrice() + " ";
  }
}
  • 具体的咖啡实现类,在构造器中设置好该单品的价格及描述
public class Decaf extends Coffee {
  public Decaf() {
    super("Decaf", 6.0);
  }
}
  • 抽象基类Decorator,通过继承和组合的方式与Drink发生关联。即它自身就是一杯咖啡,内含一个属性为,加此次原料前的咖啡。cost()等于当前单品的价格price加上属性Drinkcost()getDesccription()同理
public abstract class Decorator extends Drink {
  Drink drink;
  public Decorator(Drink drink) {
    this.drink = drink;
  }
  public Decorator(String desc, double price, Drink drink) {
    super(desc, price);
    this.drink = drink;
  }
  @Override
  public double cost() {
    return this.getPrice() + drink.cost();
  }
  @Override
  public String getDescription() {
    return drink.getDescription() + super.getDesc() + " " + super.getPrice() + " ";
  }
}
  • 具体的加料实现类,在构造器中设置好该单品的价格及描述,并接受需要被包装的Drink()
public class Milk extends Decorator {
  public Milk(Drink drink) {
    super("Milk", 2.0, drink);
  }
}
  • 调用
public class Client {
  public static void main(String[] args) {
    Drink shortBlack = new ShortBlack();
    System.out.println(shortBlack.getDescription());
    System.out.println(shortBlack.cost());

    Chocolate chocolate = new Chocolate(shortBlack); // 包装了一层
    System.out.println(chocolate.getDescription());
    System.out.println(chocolate.cost());

    Milk milk = new Milk(chocolate);  // 又包装了一层
    System.out.println(milk.getDescription());
    System.out.println(milk.cost());

    Chocolate chocolate1 = new Chocolate(milk); // 又包装了一层
    System.out.println(chocolate1.getDescription());
    System.out.println(chocolate1.cost());

  }
}