概述
动态的将新功能附加到对象上,在对象功能扩展方面它比继承更有弹性,也更体现了ocp开闭原则
使用场景
星巴克咖啡订单,单品咖啡与调料的组合
思路
使用装饰者(调料如牛奶/糖)包含被装饰者(主体咖啡/主体咖啡+调料),使用递归方式维护咖啡和调料的组合
//被装饰者
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 Coffee extends Drink {
@Override
public float cost() {
return super.getPrice();
}
}
//意大利咖啡
public class Espresso extends Coffee {
public Espresso(){
setDes("意大利咖啡");
setPrice(6.0f);
}
}
//美式咖啡
public class LongBlack extends Coffee {
public LongBlack(){
setDes("美式咖啡");
setPrice(5.0f);
}
}
//装饰者
public class Decorator extends Drink{
private Drink obj;
public Decorator(Drink obj){
this.obj = obj;
}
@Override
public float cost() {
//调料价格 + 咖啡价格
return super.getPrice() + obj.cost();
}
@Override
public String getDes() {
// super.des装饰者本身,obj.getDes()被装饰者信息
return super.des+ " && " + obj.getDes() ;
}
}
//具体的Decorator,巧克力调料
public class Chocolate extends Decorator {
public Chocolate(Drink obj) {
super(obj);
setDes("巧克力调料");
setPrice(3.0f);
}
}
//牛奶调料
public class Mink extends Decorator {
public Mink(Drink obj) {
super(obj);
setDes("牛奶调料");
setPrice(2.0f);
}
}
public class CoffeeBar {
public static void main(String[] args) {
//装饰者下订单 2份巧克力+1份牛奶+LongBlack
//1 点一份LongBlack
Drink order = new LongBlack();
System.out.println("费用1:" + order.getDes() + " 共计 " + order.cost());
//2 加一份牛奶
order = new Mink(order);
System.out.println("费用2:" + order.getDes() + " 共计 " + order.cost());
//3 加一份巧克力
order = new Chocolate(order);
System.out.println("费用3:" + order.getDes() + " 共计 " + order.cost());
}
}
运行main方法得到如下结果:
费用1:美式咖啡 共计 5.0
费用2:牛奶调料 2.0 && 美式咖啡 5.0 共计 7.0
费用3:巧克力调料 3.0 && 牛奶调料 2.0 && 美式咖啡 5.0 2.0 共计 10.0