装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。java
特色:this
举个栗子:设计
领导给你分配设计一个咖啡收款系统。咖啡能够加配料,不一样的配料收费不一样。怎么设计一个灵活的系统呢?思考三秒钟3d
若是一个顾客想要摩卡(Mocha)和奶泡(Whip)深焙咖啡(DarkRoast),使用装饰者模式怎么作呢?code
一、以DarkRoast对象开始对象
二、顾客想要摩卡(Mocha),因此创建一个Mocha对象,并用它将DarkRoast对象包(wrap)起来。blog
三、顾客也想要奶泡(Whip),因此须要创建一个Whip装饰者,并用它将Mocha对象包起来。别忘了,DarkRoast继承自Beverage,且有一个cost()方法,用来计算饮料价钱。继承
四、如今,该是为顾客算钱的时候了。经过调用最外圈装饰者(Whip)的cost()就能够办获得。Whip的cost()会先委托它装饰的对象(也就是Mocha)计算出价钱,而后再加上奶泡的价钱。ip
代码实现:get
咖啡抽象类:
public abstract class Beverage { String description = "Unknown Beverage"; public String getDescription() { return description; } public abstract double cost(); }
配料抽象类,继承咖啡抽象类:
public abstract class CondimentDecorator extends Beverage { public abstract String getDescription(); }
咖啡的实现:
// 浓咖啡 public class Espresso extends Beverage { public Espresso() { description = "Espresso"; } public double cost() { return 1.99; } } // 深焙咖啡 public class DarkRoas extends Beverage { public DarkRoas () { description = "Dark Roas Coffee"; } public double cost() { return 0.89; } }
配料实现:
public class Mocha extends CondimentDecorator { Beverage beverage; public Mocha(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Mocha"; } public double cost() { return 0.20 + beverage.cost(); } }
来一杯咖啡:
public class StarbuzzCoffee { public static void main(String args[]) { // 一杯不加配料的浓咖啡 Beverage beverage = new Espresso(); System.out.println(beverage.getDescription() + ": $" + beverage.cost()); // 双倍摩卡和奶泡深焙咖啡 Beverage beverage2 = new DarkRoast(); beverage2 = new Mocha(beverage2); beverage2 = new Mocha(beverage2); beverage2 = new Whip(beverage2); System.out.println(beverage2.getDescription() + ": $" + beverage2.cost()); // 再来一杯调料为豆浆、摩卡、奶泡的HouseBlend咖啡 Beverage beverage3 = new HouseBlend(); beverage3 = new Soy(beverage3); beverage3 = new Mocha(beverage3); beverage3 = new Whip(beverage3); System.out.println(beverage3.getDescription() + ": $" + beverage3.cost()); } }