装饰器模式

问题:假设我们有一份手抓饼,但是加不同的配菜,这样就会产生很多很多必要但重复的类:
如果用继承的话,由于配菜之间两两搭配,三三搭配都有,是十分客观的,最终导致类的数量爆炸增长

手抓饼接口和具体的一个手抓饼实现
package decorator;

/**
 * Description:手抓饼接口 描述抽象的手抓饼
 */
public interface HandPancake {

  /**
   * 提供手抓饼
   */
  String offerHandPancake();

  /**
   * 计算手抓饼的价格
   */
  Integer calcCost();
}

package decorator;

/**
 * Description: Noteless 家的手抓饼
 */
public class NotelessHandPancake implements HandPancake {

  /**
   * 提供noteless 家的手抓饼一份
   */
  @Override
  public String offerHandPancake() {
    return " noteless 家的手抓饼";
  }

  /**
   * 计算 noteless 家 一份手抓饼的价格
   */
  @Override
  public Integer calcCost() {
    return 3;
  }
}
装饰器(配菜抽象类)
package decorator;

/**
 *Description:装饰器类实现了手抓饼接口,具有了手抓饼的类型
 */
public abstract class Decorator implements HandPancake {

  private HandPancake handPancake;

  Decorator(HandPancake handPancake) {
    this.handPancake = handPancake;
  }

  /**
   * 提供手抓饼
   */
  @Override
  public String offerHandPancake() {
    return handPancake.offerHandPancake();
  }

  /**
   * 提供手抓饼的价格
   */
  @Override
  public Integer calcCost() {
    return handPancake.calcCost();
  }
具体的配菜
package decorator;

/**
 * Description:培根
 */
public class Bacon extends Decorator 
(继承的是一个手抓饼,无论是什么手抓饼)
{

  Bacon(HandPancake handPancake) {
    super(handPancake);
  }

  @Override
  public String offerHandPancake() {
    return super.offerHandPancake() + " 加培根";
  }

  @Override
  public Integer calcCost() {
    return super.calcCost() + 4;
  }
}

package decorator;

/**
 *  Description:鸡蛋
 */
public class Egg extends Decorator {

  Egg(HandPancake handPancake) {
    super(handPancake);
  }

  @Override
  public String offerHandPancake() {
    return super.offerHandPancake() + "加鸡蛋";
  }

  @Override
  public Integer calcCost() {
    return super.calcCost() + 2;
  }
}

package decorator;

/**
 *  Description:烤肠
 */
public class Sausage extends Decorator {

  Sausage(HandPancake handPancake) {
    super(handPancake);
  }

  @Override
  public String offerHandPancake() {
    return super.offerHandPancake() + " 加香肠";
  }

  @Override
  public Integer calcCost() {
    return super.calcCost() + 3;
  }
}

package decorator;

/**
 *  Description:青菜
 */
public class Vegetable extends Decorator {

  Vegetable(HandPancake handPancake) {
    super(handPancake);
  }

  @Override
  public String offerHandPancake() {
    return super.offerHandPancake() + " 加青菜";
  }

  @Override
  public Integer calcCost() {
    return super.calcCost() + 1;
  }

}
顾客部分
package decorator;

/**
 * Description:顾客具有名字,然后购买手抓饼
 */
public class Customer {

  private String name;

  Customer(String name) {
    this.name = name;
  }

  public void buy(HandPancake handPancake) {
  System.out.println(name + "购买了 : " + handPancake.offerHandPancake() +
          " 一份, 花了 : " + handPancake.calcCost() + "块钱~");
  System.out.println();
  }
}
测试类

package decorator;

/**
 *  Description: 手抓饼3块 Sausage 烤肠 3块 Bacon 培根 4块 Egg 鸡蛋2块 Vegetable
 * 青菜 1块
 */

public class Test {

  public static void main(String... strings) {

//有一个顾客张三,他想吃手抓饼了,来了一个原味的
    Customer customerA = new Customer("张三");
    customerA.buy(new NotelessHandPancake());

//有一个顾客李四,他想吃手抓饼了,他加了一根烤肠
    Customer customerB = new Customer("李四");
    customerB.buy(new Sausage(new NotelessHandPancake()));

//有一个顾客王五,他想吃手抓饼了,他加了一根烤肠 又加了培根
    Customer customerC = new Customer("王五");
    customerC.buy(new Bacon(new Sausage(new NotelessHandPancake())));

//有一个顾客王五的兄弟,他想吃手抓饼了,他加了培根 又加了烤肠
    Customer customerC1 = new Customer("王五的兄弟");
    customerC1.buy(new Sausage(new Bacon(new NotelessHandPancake())));

//有一个顾客赵六,他想吃手抓饼了,他加了一根烤肠 又加了2份培根
    Customer customerD = new Customer("赵六");
    customerD.buy(new Bacon(new Bacon(new Sausage(new NotelessHandPancake()))));

//有一个顾客 王二麻子,他想吃手抓饼了,特别喜欢吃青菜 来了三分青菜
    Customer customerE = new Customer("王二麻子");
    customerE.buy(new Vegetable(new Vegetable(new Vegetable(new NotelessHandPancake()))));

//有一个顾客 有钱人 王大富 来了一个全套的手抓饼
    Customer customerF = new Customer("王大富");
    customerF.buy(new Egg(new Vegetable(new Bacon(new Sausage(new NotelessHandPancake())))));
  }
}

最重要的部分是在装饰器(实际配菜)那里
我们可以看到,传进来并且返回的实际上还是那个手抓饼,但是配菜的方法已经被包装了一层,加入配菜的信息了,又因为这实际上还是个手抓饼,所以可以继续加 “其他配菜”

重点是啥?

 Bacon(HandPancake handPancake) {
    super(handPancake);
  }

事实上我们最外层的类一直调用的都只是最早“手抓饼”的构造器。
但是其他的方法已经被层层装饰过了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值