在如图的Component与ConcreteComponent之间,如果 ConcreteComponent类很多,还可以设计一个缓冲层,将共有的部分提取出来,抽象层一个类。
装饰者模式解决星巴克咖啡订单
示意图

Drink 类就是前面说的抽象类, Componen
ShortBlack 就单品咖啡
Decorator 是一个装饰类,含有一个被装饰的对象(Drink obj)
Decorator 的cost 方法 进行一个费用的叠加计算,递归的计算价格
装饰者模式下的订单:2份巧克力+一份牛奶的LongBlack
示意图

Milk包含了LongBlack
一份Chocolate包含了(Milk+LongBlack)
一份Chocolate包含了(Chocolate+Milk+LongBlack)
这样不管是什么形式的单品咖啡+调料组合,通过递归方式可以方便的组合和维护。
UML类图

代码示例
//是一个抽象类,表示饮料 被修饰者的最高父类
public abstract class Drink {
/**描述*/
public String des;
/**价格*/
public 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() {
//返回父类的Price值
return super.getPrice();
}
}
//具体咖啡的实现 被修饰者
public class LongBlack extends Coffee {
public LongBlack() {
setDes("LongBlack");//设置描述
setPrice(5.0f);//设置金额
}
}
public class ShortBlack extends Coffee {
public ShortBlack() {
setDes("ShortBlack");
setPrice(4.0f);
}
}
public class Espresso extends Coffee {
public Espresso() {
setDes("意大利咖啡");
setPrice(6.0f);
}
}
//-----------------------------------------------------------------------------
//装饰器 定义规范/公共内容
public class Decorator extends Drink {
//被装饰者对象
private Drink obj;
//构造器
public Decorator(Drink obj) {
this.obj = obj;
}
@Override
public float cost() {
//super.getPrice() 拿到自己价格
//返回 当前对象的价格 + obj.cost()被修饰者的价格 计算形式和递归相似
return super.getPrice() + obj.cost();
}
@Override
public String getDes() {
//obj.getDes() 被装饰者的信息 会以递归的形式拼接字符串
return des + " " + getPrice() + " && " + obj.getDes();
}
}
//具体调味料的实现 充当修饰者角色
public class Chocolate extends Decorator {
public Chocolate(Drink obj) {
super(obj);//传入被修饰者
setDes("巧克力");//描述
setPrice(3.0f);//调味品价格
}
}
public class Milk extends Decorator{
public Milk(Drink obj) {
super(obj);
setDes("牛奶");
setPrice(2.0f);
}
}
public class Soy extends Decorator {
public Soy(Drink obj) {
super(obj);
setDes("豆浆");
setPrice(1.5f);
}
}
//-----------------------------------------------------------------------------
//咖啡店 调用测试
public class CoffeeBar {
public static void main(String[] args) {
//装饰者模式下的订单:2份巧克力+一份牛奶的LongBlack
//1.点一份LongBlack
Drink order = new LongBlack();
System.out.println("一份LongBlack费用 = " + order.cost());
System.out.println("一份LongBlack描述 = " + order.getDes());
//2.order 加入一份牛奶
order = new Milk(order);
System.out.println("order 加入一份牛奶后费用 = " + order.cost());
System.out.println("order 加入一份牛奶后描述 = " + order.getDes());
//3.order 加入一份巧克力
order = new Chocolate(order);
System.out.println("order 加入一份巧克力后费用 = " + order.cost());
System.out.println("order 加入一份巧克力后描述 = " + order.getDes());
//3.order 加入两份巧克力
order = new Chocolate(order);
System.out.println("order 加入两份巧克力后费用 = " + order.cost());
System.out.println("order 加入两份巧克力后描述 = " + order.getDes());
}
}
装饰者模式在JDK应用的源码分析