1. 程序说明
新开了一家咖啡店,可以往咖啡里面加各种配料,牛奶、糖、奶泡等。按照面向对象的设计中,我们最先想到的是设计一个简单咖啡类,然后分别设计加牛奶的咖啡,加糖的咖啡,加奶泡的咖啡去继承简单咖啡类,但是当有一天,配料越来越多,而且用户需求越来越千奇百怪,比如加糖的同时又要加奶泡……那么子类会灾难性地增长,装饰者模式为解决这个而生,提供了比继承更好的解决方法。
2. UML
3. Java实现
Coffee
package decorator_pattern.coffee;
public abstract class Coffee {
public abstract float getPrice();
public abstract void getTaste();
}
Decorator
package decorator_pattern.coffee;
public class Decorator extends Coffee {
public Coffee coffee;
public Decorator(Coffee coffee) {
this.coffee = coffee;
}
public float getPrice(){
return coffee.getPrice();
}
public void getTaste(){
coffee.getTaste();
}
}
MilkDecorator
package decorator_pattern.coffee;
public class MilkDecorator extends Decorator {
private final static float MILK_PRICE = 5f;
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public float getPrice() {
return coffee.getPrice() + MILK_PRICE;
}
@Override
public void getTaste() {
coffee.getTaste();
System.out.println("加一点点牛奶的口味");
}
}
SugarDecorator
package decorator_pattern.coffee;
public class SugarDecorator extends Decorator {
private final static float SUGER_PRICE = 6f;
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public float getPrice() {
return coffee.getPrice() + SUGER_PRICE;
}
@Override
public void getTaste() {
coffee.getTaste();
System.out.println("加点糖,甜甜的");
}
}
SimpleCoffee
package decorator_pattern.coffee;
public class SimpleCoffee extends Coffee {
private final static float PRICE = 50f;
@Override
public float getPrice() {
return PRICE;
}
@Override
public void getTaste() {
System.out.println("普通咖啡口味");
}
}
Test
package decorator_pattern.coffee;
public class Test {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);
System.out.println("最终咖啡价格:" + coffee.getPrice());
System.out.print("最终咖啡口味: \n");
coffee.getTaste();
}
}
/**
最终咖啡价格:61.0
最终咖啡口味:
普通咖啡口味
加一点点牛奶的口味
加点糖,甜甜的
**/
4. 总结
可以把类中的装饰功能从类中移除,从而简化原来的类,即把类的核心职责和装饰功能分开,结构清晰、明了,并可以去除相关类的装饰逻辑。