问题:假设我们有一份手抓饼,但是加不同的配菜,这样就会产生很多很多必要但重复的类:
如果用继承的话,由于配菜之间两两搭配,三三搭配都有,是十分客观的,最终导致类的数量爆炸增长
手抓饼接口和具体的一个手抓饼实现
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);
}
事实上我们最外层的类一直调用的都只是最早“手抓饼”的构造器。
但是其他的方法已经被层层装饰过了