装饰模式:动态的将责任附加到对象上,想要扩展功能,装饰者提供有别于继承的另一种选择。
1,创建顶级类
package com.pattern.decorate; public abstract class Beverage { String description = "Unknown Beverage"; public String getDescription(){ return description; } public abstract double cost(); }
2,创建产品类
package com.pattern.decorate; public class Espresso extends Beverage{ public Espresso(){ description = "Espresso"; } /** * @see com.pattern.decorate.Beverage#cost() */ @Override public double cost() { return 1.99; } }
package com.pattern.decorate; public class HouseBlend extends Beverage{ public HouseBlend(){ description = "House Blend Coffee"; } /** * @see com.pattern.decorate.Beverage#cost() */ @Override public double cost() { return .89; } }
package com.pattern.decorate; public class DarkRoast extends Beverage { public DarkRoast(){ description = "DarkRoast"; } /** * @see com.pattern.decorate.Beverage#cost() */ @Override public double cost() { return 2.99; } }
3,创建装饰类
package com.pattern.decorate; public abstract class CondimentDecorator extends Beverage{ public abstract String getDescription(); }
4,创建装饰类的具体实现类
package com.pattern.decorate; public class Whip extends CondimentDecorator { public Beverage beverage; public Whip(Beverage beverage) { this.beverage = beverage; } /** * @see com.pattern.decorate.CondimentDecorator#getDescription() */ @Override public String getDescription() { return beverage.getDescription()+", Whip"; } /** * @see com.pattern.decorate.Beverage#cost() */ @Override public double cost() { return .30+beverage.cost(); } }
package com.pattern.decorate; public class Mocha extends CondimentDecorator{ Beverage beverage; public Mocha(Beverage beverage){ this.beverage = beverage; } /** * @see com.pattern.decorate.CondimentDecorator#getDescription() */ @Override public String getDescription() { return beverage.getDescription()+", Mocha"; } /** * @see com.pattern.decorate.Beverage#cost() */ @Override public double cost() { return .20+beverage.cost(); } }
5,测试
package com.pattern.decorate; 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()); } }
上图装饰类与被装饰类 具有共同的父类。
其实也可以不具有相同的父类!