设计模式之装饰
来源:互联网 发布:关闭电脑软件自动更新 编辑:程序博客网 时间:2024/06/10 15:01
模式定义
装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
模式结构
UML类图:
代码分析
有这样一个项目,做一个餐厅订餐系统。起初的代码结构是这样的。前面有很多Beverage的继承类,现在遇到的问题是牛奶的价钱上涨了,那么所有相关的类,我们都要进行调整,比如Milk,SugarAndMilk类,这种类还有很多,我们需要逐个去修改类中的方法——开发人员每次都做这种事情,要疯了!所以我们要改变现有的结构。以下的图都是简图,实际的图,可没有这么简单。
开发中遇到的设计问题:
1类数量爆炸,有很多类,难以维护;
2整个设计呆板;
3基类加入的新功能无法使用于子类;
复用类方法的方式很多,比如继承,组合,委托。为什么老是习惯用继承呢?
我们决定把基础类抽出来,比如,我们把咖啡做成一个单独的类,其他的咖啡,比如牛奶咖啡,甜味咖啡,我们只对材料单独包装成一个类。
经过改良的设计:
详解
1对于饮品,我们直接继承Beverage类,直接把报价写进饮品类里面;
2而对于一些需要添加调味品的特殊饮品,我们做累加操作。比如,我想要杯奶咖啡,则 总价=咖啡价+奶价
3这样不同的饮料就很容易知道它的价格。
<?phpabstract class Beverage{ public $_name; abstract public function Cost();}// 被装饰者类class Coffee extends Beverage{ public function __construct(){ $this->_name = 'Coffee'; } public function Cost(){ return 1.00; } }// 以下三个类是装饰者相关类class CondimentDecorator extends Beverage{ public function __construct(){ $this->_name = 'Condiment'; } public function Cost(){ return 0.1; } }class Milk extends CondimentDecorator{ public $_beverage; public function __construct($beverage){ $this->_name = 'Milk'; if($beverage instanceof Beverage){ $this->_beverage = $beverage; }else exit('Failure'); } public function Cost(){ return $this->_beverage->Cost() + 0.2; } }class Sugar extends CondimentDecorator{ public $_beverage; public function __construct($beverage){ $this->_name = 'Sugar'; if($beverage instanceof Beverage){ $this->_beverage = $beverage; }else{ exit('Failure'); } } public function Cost(){ return $this->_beverage->Cost() + 0.2; }}// Test Case//1.拿杯咖啡$coffee = new Coffee();//2.加点牛奶$coffee = new Milk($coffee);//3.加点糖$coffee = new Sugar($coffee);printf("Coffee Total:%0.2f元\n",$coffee->Cost());?>
优点
样的模型很具有扩者性,我们可以轻松的添加其他装饰器给区域对象,且不需要更改其他类,像建立了一个管道,装饰器模式经常被用于创建过滤器。
总结
装饰者(Milk)和被装饰者(Coffee)必须是一样的类型。目的是装饰者必须取代被装饰者。
添加行为:当装饰者和组件组合时,就是在加入新的行为。
0 0
- 设计模式之装饰
- 设计模式之装饰
- 设计模式之装饰
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之 装饰模式
- 设计模式之-装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- 设计模式之装饰模式
- Linux_VIM
- CoordinatorLayout的使用如此简单
- GridView绑定数据的方法
- bzoj1087: [SCOI2005]互不侵犯King
- CENTOS: Docker Pull下来的TOMCAT Image安装东西。
- 设计模式之装饰
- Bootstrap学习笔记(三)表单
- React Native 指定 style
- android截屏 (非root,只限当前acitvity当中)
- 多个线程之间如何进行通信
- FCN-for-semantic-image-segmentation 训练过程的一些坑记录_0
- 夕拾算法进阶篇:20)货币系统 (完全背包_动态规划DP)
- 多个文件打包下载 java
- 使用consul实现分布式服务注册和发现