1、uml类图
2、两个对象
主体:被装饰的对象(打包)
包装:包装核心类,即各个在类中继承Decorator的调料类
3、代码
//包装核心类(包装)
package test.decorator;
/**
* 包装类
*/
public class Decorator extends Drink{
private Drink drink;
public Decorator(Drink drink){
this.drink = drink;
}
//计算总金额
@Override
public float cost() {
return super.getPrice() + drink.cost();
}
//打印被装饰者的信息
@Override
public String getDes(){
return des + " " + getPrice() + " && " + drink.getDes();
}
}
包装类子类
public class Chocolate extends Decorator{
public Chocolate(Drink drink) {
super(drink);
setDes("巧克力");
setPrice(0.2f);
}
}
public class Soy extends Decorator{
public Soy(Drink drink) {
super(drink);
setDes("豆浆");
setPrice(0.1f);
}
}
被包装类
//缓冲
public class Coffee extends Drink{
@Override
public float cost() {
return super.getPrice();
}
}
public class AmericanCoffee extends Coffee{
public AmericanCoffee(){
setDes("AmericanCoffee");
setPrice(0.6f);
}
}
public class EnglishCoffee extends Coffee{
public EnglishCoffee(){
setDes("EnglishCoffee");
setPrice(0.4f);
}
}
运行代码
public class RunMain {
public static void main(String[] args) {
//1、要一份加了巧克力的英式咖啡
Drink drink = new EnglishCoffee();
System.out.println("价格----"+drink.cost());
System.out.println("名称----"+drink.getDes());
//2、要巧克力
drink = new Chocolate(drink);
System.out.println("价格----"+drink.cost());
System.out.println("名称----"+drink.getDes());
//3、加豆浆
drink = new Soy(drink);
System.out.println("价格----"+drink.cost());
System.out.println("名称----"+drink.getDes());
}
}
运行结果
由于没有使用BigDecimal进行精度运算,可能存在精度问题。
4、装饰者模式的好处
1)动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)
如果需要新增功能,只需要新增一个对象继承缓冲层对象即可,照样能使用包装类对改对象进行包装