开放原则:类应该对扩展开放,对修改关闭。
- 上篇博客中的观察者模式中,通过加入新的观察者,我们可以在任何时候扩展主题(Subject),而且不需向主题中添加代码。
- 装饰者模式也完全遵循开放原则。
装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
记住:是你,还有你,一切拜托你。
是你:包装类继承(或实现)被包装类
还有你:包装类包含被包装类的一个实例
一切拜托你:非增强方法全部拜托 被包装类的实例来完成
增强方法:根据需求重写方法
代码
/** * 饮料 * @author oy * @date 2019年8月28日 下午11:07:33 * @version 1.0.0 */ public abstract class Beverage { public String description; public String getDescription() { return description; } public abstract double cost(); // 其他方法 public abstract String method1(); }
CondimentDecorator
/** * 装饰类 = 饮料 + 调料 * @author oy * @date 2019年8月28日 下午11:13:55 * @version 1.0.0 */ public abstract class CondimentDecorator extends Beverage { public abstract String getDescription(); // 空实现 public String method1() { return ""; } }
Espresso
/** * 浓缩咖啡 */ public class Espresso extends Beverage { public Espresso() { description = "Espresso"; } @Override public double cost() { return 1.0; } @Override public String method1() { return "Espresso method1()"; } }
HouseBlend
/** * House Blend Coffee*/ public class HouseBlend extends Beverage { public HouseBlend() { description = "House Blend Coffee"; } @Override public double cost() { return 2.0; } @Override public String method1() { // TODO Auto-generated method stub return "HouseBlend method1()"; } }
Mocha
/** * 具体的装饰类:是你,还有你,一切拜托你。*/ public class Mocha extends CondimentDecorator {//是你:Mocha是Beverage类型 Beverage beverage; // 还有你:Mocha包含Beverage的对象实例 public Mocha(Beverage beverage) { this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription() + ", Mocha"; } // 一切拜托你:Beverage的不需要增强的方法全部拜托给beverage对象来处理 @Override public String method1() { return beverage.method1(); } // 重写增强方法 @Override public double cost() { return 0.20 + beverage.cost(); } }
Whip
/** * 具体的装饰类:是你,还有你,一切拜托你。 * @author oy * @date 2019年9月1日 上午10:06:53 * @version 1.0.0 */ public class Whip extends CondimentDecorator {//是你 Beverage beverage; // 还有你 public Whip(Beverage beverage) { this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription() + ", Whip"; } @Override public String method1() { return beverage.method1(); } // 增强方法 @Override public double cost() { return 0.30 + beverage.cost(); } }
测试代码
public static void main(String[] args) { Beverage beverage = new Espresso(); System.out.println(beverage.getDescription() + " $" + beverage.cost()); System.out.println(beverage.method1()); // 用摩卡装饰Espresso(浓缩饮料) Beverage mocha = new Mocha(beverage); System.out.println(mocha.getDescription() + " $" + mocha.cost()); System.out.println(mocha.method1()); // 还可以继续装饰mocha mocha = new Whip(mocha); System.out.println(mocha.getDescription() + " $" + mocha.cost()); System.out.println(mocha.method1()); }
打印结果:
Espresso $1.0 Espresso method1() Espresso, Mocha $1.2 Espresso method1() Espresso, Mocha, Whip $1.5 Espresso method1()