Head First Java 设计模式——装饰者模式
来源:互联网 发布:mac os山狮系统 编辑:程序博客网 时间:2024/06/02 07:29
装饰者模式,动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更具有弹性的替代方案。书中给出的是一个星巴兹的实例,他们准备更新订单系统,原先的类设计如下:
现在要实现,当客户购买咖啡时,可以要求加入各种调料,例如Milk、Soy、Mocha等,然后加入的调料会收取不同的费用。我们可能会按如下方法去尝试:
为每一种咖啡都建一个类,但是这样就会出现"类爆炸"的问题了。于是你可能想到要通过修改Beverage:
public abstract class Beverage {String description = "Unknown Beverage";boolean milk;boolean soy;boolean mocha;boolean whip;public boolean hasMilk();public void setMilk();public boolean hasSoy();public void setSoy();public boolean hasMocha();public void setMocha();public boolean hasWhip();public void setWhip();public String getDescription() {return description;}public double cost();}
这个时候cost()不是一个抽象方法,让它计算要加入的各种调料的价钱,然后子类仍将覆盖cost(),但是会调用超类的cost(),计算出基本饮料加上调料的价钱。但是这样又会出现几个问题:
1、一旦出现新的调料,我们就要加上新的方法,并改变超类的cost()方法。
2、以后可能会开发出新饮料,新的饮料某些调料可能不适合,但是这个设计方式,新的子类仍将要继承那些不适合的方法。
3、万一顾客想要双倍摩卡咖啡呢。
下面采用新的方法:以饮料为主题,然后在运行时以调料来“装饰”饮料。用代码的方式呈现如下:
先从Beverage类下手:
public abstract class Beverage {String description = "Unknown Beverage";public String getDescription() {return description;}public abstract double cost();}
然后实现Condiment(调料)抽象类,也就是装饰者类:
public abstract class CondimentDecorator extends Beverage {public abstract String getDescription();}
接下来写饮料的代码,例如浓缩咖啡(Espresso),家常咖啡(HouseBlend):
public class Espresso extends Beverage {public Espresso() {description = "Espresso";}public double cost() {return 1.99;}}public class HouseBlend extends Beverage {public HouseBlend() {description = "House Blend Coffee";}public double cost() {return 0.89;}}
写调料代码,例如摩卡(Mocha):
public class Mocha extends CondimentDecorator {Beverage beverage;public Mocha(Beverage beverage) {this.beverage = beverage;}public String getDescription() {return beverage.getDescription() + ", Mocha";}public double cost() {//这里计算带Mocha饮料的价钱,先把调用委托给被装饰对象,再加上Mocha的价钱,得到最终结果。return 0.20 + beverage.cost();}}
最后,我们可以通过下面的方式来使用:
public class StarBuzzCoffee {public static void main(String args[]) {//订一杯Espresso,不需要调料。Beverage beverage = new Espresso();System.out.println(beverage.getDescription() + "$" + beverage.cost());//订一杯DarkRost咖啡。Beverage beverage2 = new DarkRost();//用Mocha装饰它。beverage2 = new Mocha(beverage2);//用第二个Mocha装饰它。beverage2 = new Mocha(beverage2);//用Whip装饰它。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());}}
这一章提到的设计原则:
1、开放-关闭原则(类应该对扩展开放,对修改关闭)。
- Head First Java 设计模式——装饰者模式
- Head First 设计模式学习——装饰者模式
- Head First 设计模式—装饰者模式
- Head First设计模式-装饰者模式
- 《Head First 设计模式》装饰者模式
- Head First 设计模式--装饰者模式
- Head First-设计模式:装饰者模式
- 《Head First设计模式》读书笔记3——装饰模式
- Head First 设计模式 —— 装饰器模式
- 【设计模式】《Head First 设计模式》读书笔记——装饰者模式
- 《Head First 设计模式》学习笔记——观察者模式 + 装饰者模式
- 《Head First 设计模式》模式3——装饰者模式
- java设计模式-Head First设计模式之装饰者模式
- 《Head First 设计模式》阅读笔记(三)——装饰者模式
- Head First 设计模式——装饰者模式(Decorator Pattern)
- 读书笔记3:Head First设计模式——装饰者模式
- 《Head First 设计模式》学习笔记——装饰者模式
- Head First 设计模式学习笔记——装饰者模式
- 培训教材
- ubuntu下commonlisp配置
- JAVA的各种O
- 关于jdk中类装载器ClassLoader扩展和JNI技术(JavaNativeInterface)以及类文件的加密解密算法
- 实战:rman异机duplicate active数据库
- Head First Java 设计模式——装饰者模式
- 牛人推荐的软件测试读书列表
- showModelDialog的用法。
- java关于深复制示例
- Android 悬浮Activity并可拖动(访悬浮歌词)
- 控制文件损坏的恢复
- python 学习记录(1)—对内建str的处理
- eclipse
- java中关于I/O的效率问题