Head First: 装饰者模式

来源:互联网 发布:福彩内部数据 编辑:程序博客网 时间:2024/05/22 03:44

1. 装饰者模式UML类图


     

2. 装饰者模式要点
   装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
   结合类图,总结装饰者模式要点如下:
   a. 组合和委托可用于在运行时动态地加上新的行为。
   b. 装饰者模式意味着一群装饰者类,这些类用来包装具体组件。
   c. 装饰者类反映出被装饰的组件类型(事实上,他们具有相同的类型,都经过接口或继承实现)。
   d. 装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得更复杂。
3. 装饰者模式实现

   参照类图,以Coffee(咖啡)为组件(Component),Mocha(摩卡)、Soy(豆浆)、Milk(牛奶)为装饰者(Decorator)实现装饰者模式。

/** * 咖啡类(超类) */public abstract class Coffee {/** 咖啡信息描述 */protected String desc = "Unknown Beverage";public String getDescription() {return desc;}/** 花费 */public abstract double cost();}/** * 调料抽象类,也是是装饰者类(装饰咖啡) */public abstract class CondimentDecorator extends Coffee {/** 被装饰者 */protected Coffee coffee;public CondimentDecorator(Coffee cof) {coffee = cof;}/** * 所有子类都需要重新实现getDescription()方法 */public abstract String getDescription();}/** * Espresso,咖啡的一种 */public class Espresso extends Coffee {public Espresso() {this.desc = "Espresso"; }@Overridepublic double cost() {return 1.99;}}/** * HouseBlend,咖啡的一种 */public class HouseBlend extends Coffee {public HouseBlend() {this.desc = "HouseBlend";}@Overridepublic double cost() {return 0.89;}}/** * Mocha,摩卡,是咖啡调料的一种。 */public class Mocha extends CondimentDecorator {public Mocha(Coffee cof) {super(cof);}@Overridepublic String getDescription() {return coffee.getDescription() + ", Mocha";}@Overridepublic double cost() {return coffee.cost() + 0.2;}}/** * Soy,豆浆,可用作咖啡调料。 */public class Soy extends CondimentDecorator {public Soy(Coffee cof) {super(cof);}@Overridepublic String getDescription() {return coffee.getDescription() + ", Soy";}@Overridepublic double cost() {return coffee.cost() + 0.15;}}/** * Milk,牛奶,可用作咖啡调料。 */public class Milk extends CondimentDecorator {public Milk(Coffee cof) {super(cof);}@Overridepublic String getDescription() {return coffee.getDescription() + ", Milk";}@Overridepublic double cost() {return coffee.cost() + 0.25;}}/** * 测试类 */public class DecoratorTester {/** * 测试方法 */public void test() {/** 客户只点了一杯Espresso咖啡 */Coffee coffee = new Espresso();System.out.println(coffee.getDescription() + " $" + coffee.cost());/** 客户点了一杯HouseBlend咖啡,外加一份Mocha调料、一份Soy调料、一份Milk调料。 */Coffee coffee2 = new HouseBlend();coffee2 = new Mocha(coffee2);coffee2 = new Soy(coffee2);coffee2 = new Milk(coffee2);System.out.println(coffee2.getDescription() + " $" + coffee2.cost());/** 客户点了一杯HouseBlend咖啡,两份Mocha调料。 */Coffee coffee3 = new HouseBlend();coffee3 = new Mocha(coffee3);coffee3 = new Mocha(coffee3);System.out.println(coffee3.getDescription() + " $" + coffee3.cost());}}


4. 运行结果

    

0 0