装饰者模式:动态地将责任附加到对象上,若到扩展功能,装饰者提供了比继承更有弹性的替代方案。
UML图
有这样一个需求,咖啡店出售各式咖啡,如深焙、低卡、摩卡等,也有各种调料,如牛奶、奶泡等。
咖啡店需要根据咖啡中所放入的不同调料收取不同的费用。用装饰者模式来实现
定义一个抽象组件
package com.headfirst.chapter3; /** * 定义了一个抽象类,用于表示组件,它定义了一个抽象方法cost */ public abstract class Beverage { String description; public String getDescription() { return description; } public abstract double cost();//计费方法 }
下面两个是具体组件,也就是被装饰者
1,深焙咖啡
package com.headfirst.chapter3; public class DarkRoast extends Beverage {//深焙咖啡 public DarkRoast() { this.description = "DarkRoast"; } public double cost() { return 0.89; } }
2,混合咖啡
package com.headfirst.chapter3; public class HouseBlend extends Beverage { public HouseBlend() { this.description = "HouseBlend"; } public double cost() { return 1.89; } }
装饰者
这里定义了一个抽象方法getDescription,那么子类必须它来增加描述
如Houseblend Milk
package com.headfirst.chapter3; public abstract class CondimentDecorator extends Beverage { public abstract String getDescription(); }
下面两个是装饰者
package com.headfirst.chapter3; public class Milk extends CondimentDecorator { private Beverage beverage;//这个引用指向被装饰者 public Milk(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + " Milk"; } public double cost() { return beverage.cost() + 0.20; } }
package com.headfirst.chapter3; public class Mocha extends Beverage { Beverage beverage; public Mocha(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + " Mocha"; } public double cost() { return beverage.cost()+0.59; } }
测试类:
package com.headfirst.chapter3; public class Test { public static void main(String[] args) { Beverage darkRoast = new DarkRoast(); darkRoast = new Mocha(darkRoast); darkRoast = new Milk(darkRoast); System.out.println(darkRoast.getDescription()+" $"+darkRoast.cost()); } }
最后打印出:DarkRoast Mocha Milk $1.68