Head First 装饰者模式
一、类图
二、示例代码
类图:
代码:
1、饮料类
/** * 饮料类 */ public abstract class Beverage { public String description = "Unknown Beverage"; public String getDescription(){ return description; } public abstract double cost(); }
2、具体饮料类
public class Espresso extends Beverage { public Espresso() { description = "Espresso"; } @Override public double cost() { return 1.99; } } public class HouseBlend extends Beverage { public HouseBlend() { description = "House Blend Coffee"; } @Override public double cost() { return 0.89; } }
3、调料 类,必须让CondimentDecorator能够取代Beverage,所以将CondimentDecorator扩展自Beverage
/** * 调料类 */ public abstract class CondimentDecorator extends Beverage{ public abstract String getDescription(); }
4、具体调料类
public class Mocha extends CondimentDecorator { Beverage beverage; public Mocha(Beverage beverage) { this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription() + ", Mocha"; } @Override public double cost() { return 0.2 + beverage.cost(); } } public class Soy extends CondimentDecorator { Beverage beverage; public Soy(Beverage beverage) { this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription() + ", Soy"; } @Override public double cost() { return 0.3 + beverage.cost(); } } public class Whip extends CondimentDecorator { Beverage beverage; public Whip(Beverage beverage) { this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription() + ", Whip"; } @Override public double cost() { return 0.4 + beverage.cost(); } }
5、订单测试类
/** * 咖啡供应类 */ public class StarbuzzCoffee { public static void main(String[] args) { //订一杯Espresso,不需要调料 Beverage beverage = new Espresso(); System.out.println(beverage.getDescription() + " $" + beverage.cost()); //来一杯调料为豆浆、摩卡、奶泡的HouseBlend咖啡 Beverage beverage1 = new HouseBlend(); beverage1 = new Soy(beverage1); beverage1 = new Mocha(beverage1); beverage1 = new Whip(beverage1); System.out.println(beverage1.getDescription() + " $" + beverage1.cost()); } }
三、使用场景
需要扩展一个类的功能,或给一个类增加附加功能。
需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
需要为一批的兄弟类进行改装或加装功能,当然是首选装饰模式。