【设计模式】《Head First 设计模式》读书笔记——装饰者模式
来源:互联网 发布:淘宝窗帘拍摄技巧 编辑:程序博客网 时间:2024/05/29 12:52
装饰者模式:
动态地将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。
涉及设计模式:
1.多用组合,少用继承
2.类应该对扩展开放,对修改关闭
问题简单描述:
星巴克有很多饮料。一开始的设计是有一个饮料超类(包含getDescription()、cost()方法),所有的饮料都继承这个饮料超类,但是饮料的种类非常的多,使得类的种类非常非常多,简直是“类爆炸”。后来又想到另外一种饮料基类,增加了包含了各种调料的布尔值,还有获取是否含有各种调料的方法,设置各种调料的方法,cost方法根据调料的布尔值判断是否加调料的价钱得出饮料的价格。只需要几种基本的饮料继承饮料基类,通过设置不同的调料就可以得到大部分的饮料,从而解决了类爆炸的问题。但是仍然存在很多问题,调料的价格调整或者新调料出现就需要改变基类的代码,也有一些饮料无法通过这样的方法表示(如双倍摩卡咖啡,因为一个调料在基类只有一个布尔值,虽然通过改变基类可以实现,但是基类变得复杂)。
解决思路:
用调料来“装饰”(包装可能更好理解)基本的饮料,每次计算价格的时候调用最外圈的cost(),外圈的cost()委托里层cost()来计算直到递归到最里层的基本饮料,再一层层的返回到最外层,没经过一层都会加上那一层的价格。
UML图:
实现代码:
Beverage基类:package decorator;
/** * 饮料超类(装饰者基类) * @author terry * */public abstract class Beverage {String description="Unkonwn Beverage";public String getDescription() {return description;}public abstract double cost();}
基本饮料
package decorator;/** * 低咖啡因咖啡(基本饮料) * @author terry * */public class Decaf extends Beverage{public Decaf(){description="Decaf";}@Overridepublic double cost() {return 0.9;}}
package decorator;/** * 浓缩咖啡(基本饮料) * */public class Espresso extends Beverage {public Espresso(){description="Espresso";}@Overridepublic double cost() {return 1.99;}}
调料超类(也需要继承饮料超类)
package decorator;/** * 调料装饰者超类(也需要继承饮料超类,达到跟基本饮料属于同一个类型) * @author terry * */public abstract class CondimentDecorator extends Beverage {public abstract String getDescription();}
调料实现类
package decorator;/** * 摩卡(调料实现类) * @author terry * */public class Mocha extends CondimentDecorator{//调料实现类需要有饮料属性,需要有被装饰者Beverage beverage;public Mocha(Beverage beverage){this.beverage=beverage;}@Overridepublic String getDescription() {return beverage.getDescription()+",Mocha";}@Overridepublic double cost() {//计算价格先把调用委托给装饰对象,计算出价格后再加上摩卡本身的价格return beverage.cost()+0.3;}}
package decorator;/** * 奶泡(调料实现类) * @author terry * */public class Whip extends CondimentDecorator {Beverage beverage;public Whip(Beverage beverage){this.beverage=beverage;}@Overridepublic String getDescription() {return beverage.getDescription()+",Whip";}@Overridepublic double cost() {return beverage.cost()+0.2;}}
测试类
package decorator;public class Test {public static void main(String[] args){//双摩卡奶泡浓缩咖啡Beverage beverage=new Espresso();beverage=new Mocha(beverage);beverage=new Whip(beverage);beverage=new Mocha(beverage);/* * 可能这样写更有包裹的感觉 * beverage=new Mocha(new Whip(new Mocha(beverage))); */System.out.println(beverage.getDescription()+" cost:"+beverage.cost());}}
输出结果
欢迎批评指正^ ^
0 0
- 《Head First设计模式》读书笔记3——装饰模式
- 【设计模式】《Head First 设计模式》读书笔记——装饰者模式
- 《Head First 设计模式》读书笔记之装饰者模式
- 【Head First设计模式-读书笔记】装饰者模式
- 读书笔记---Head First 设计模式--- 装饰者模式
- Head First Java 设计模式——装饰者模式
- Head First 设计模式学习——装饰者模式
- Head First 设计模式—装饰者模式
- 读书笔记3:Head First设计模式——装饰者模式
- Head First设计模式-装饰者模式
- 《Head First 设计模式》装饰者模式
- Head First 设计模式--装饰者模式
- Head First-设计模式:装饰者模式
- 《Head First设计模式》读书笔记之装饰模式
- Head First 设计模式 —— 装饰器模式
- Head First设计模式读书笔记
- 读书笔记-《Head First 设计模式》
- 读书笔记《Head First设计模式》
- python2
- swiper.animate
- 网络编程——socket套接字的使用(一)
- 推免后的生活(16/11/4~27)
- android graphic(6)—surfaceflinger和MessageQueue
- 【设计模式】《Head First 设计模式》读书笔记——装饰者模式
- 10张图带你深入理解Docker容器和镜像
- cqround_7 游记
- 今日学习感悟
- //6. ZigZag Conversion --String类型
- AngularJS (一)
- ubutn16.04安装google浏览器
- php后台与客户端交互
- 【u033】地震逃生