装饰者模式

定义与特定

装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

装饰器模式主要包含以下角色。

  1. 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
  2. 具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
  3. 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
  4. 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

装饰者模式的主要优点有:

  • 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
  • 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
  • 装饰器模式完全遵守开闭原则

其主要缺点是:装饰器模式会增加许多子类,过度使用会增加程序得复杂性。

UML图与代码

 

public abstract class Drink {
/**描述*/
  private String des;
  private float price = 0.0f;

  /**
   * 计算总价格
   * @return
   */
  public abstract float cost();
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 class Coffee extends Drink{ @Override public float cost() { return super.getPrice(); } }
public class Espresso extends Coffee{
    public Espresso() {
        setDes("意大利咖啡");
        setPrice(6.0f);
    }

    @Override
    public String getDes() {
        return super.getDes()+" "+this.getPrice();
    }
}
public class Decorator extends Drink{

private Drink drink;

public Decorator(Drink drink) {
this.drink = drink;
}

@Override
public float cost() {
//super.getPrice():修饰者价格,drink.cost()被修饰者价格
return super.getPrice()+drink.cost();
}

@Override
public String getDes() {
return super.getDes()+" "+super.getPrice()+" "+drink.getDes();
}
}
public class MilkDecorator extends Decorator{ 

public MilkDecorator(Drink drink) {
  super(drink);
  setDes(
"牛奶");
  setPrice(
2.0f);
  }
}

public class ChocolateDecorator extends Decorator{

  public ChocolateDecorator(Drink drink) {

    super(drink);
    setDes(
"巧克力");
  
    //巧克力价格
    setPrice(3.0f);
     }
  }

public class Client {

  public static void main(String[] args) {

  //不加调味品
  
Espresso espresso = new Espresso();
  System.out.println(espresso.getDes());

  //加牛奶的意大利咖啡
  MilkDecorator milkEspresso = new MilkDecorator(new Espresso());
  System.out.println(milkEspresso.getDes());

  //加牛奶,巧克力的意大利咖啡
  MilkDecorator milkChocolateEspresso = new MilkDecorator(new ChocolateDecorator(new Espresso()));
  System.out.println(milkChocolateEspresso.getDes());
  }
}

输出:

意大利咖啡 6.0
牛奶 2.0 意大利咖啡 6.0
牛奶 2.0 巧克力 3.0 意大利咖啡 6.0

原文地址:https://www.cnblogs.com/isalo/p/15420509.html