用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字

小蜜锋    -  云代码空间

—— 技术宅拯救世界!

PHP 装饰器模式(php设计模式)

2013-06-06|2325阅||

摘要:介绍 装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。   思维导图   有这样一个项目,做一个餐厅订餐系统。起初的代码结构是这样的。前面有很多Beverage的继承类,现在遇到的问题是牛

介绍
装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
 
思维导图

装饰者模式

 

有这样一个项目,做一个餐厅订餐系统。起初的代码结构是这样的。前面有很多Beverage的继承类,现在遇到的问题是牛奶的价钱上涨了,那么所有相关的类,我们都要进行调整,比如Milk,SugarAndMilk类,这种类还有很多,我们需要逐个去修改类中的方法——开发人员每次都做这种事情,要疯了!所以我们要改变现有的结构。以下的图都是简图,实际的图,可没有这么简单。

 

 

 设计问题:

1》类数量爆炸,有很多类,难以维护;

2》整个设计呆板;

3》基类加入的新功能无法使用于子类;

 

复用类方法的方式很多,比如继承,组合,委托。为什么老是习惯用继承呢?我看Zend Framework也有这种习惯!每次找对应方法,一直往上翻。——题外话!!!!

 

 后来经过小组研究决定,我们决定把基础类抽出来,比如,我们把咖啡做成一个单独的类,其他的咖啡,比如牛奶咖啡,甜味咖啡,我们只对材料单独包装成一个类。

经过改良的设计:

 

详解

1》对于饮品,我们直接继承Beverage类,直接把报价写进饮品类里面;

2》而对于一些需要添加调味品的特殊饮品,我们做累加操作。比如,我想要杯奶咖啡,则 总价=咖啡价+奶价

3》这样不同的饮料就很容易知道它的价格。

 

代码
 

<?php
abstract class Beverage{
    public $_name;
    abstract public function Cost();
}
// 被装饰者类
class Coffeeextends Beverage{
    public function __construct(){
        $this->_name ='Coffee';
    }  
    public function Cost(){
        return 1.00;
    }  
}
// 以下三个类是装饰者相关类
class CondimentDecoratorextends Beverage{
    public function __construct(){
        $this->_name ='Condiment';
    }  
    public function Cost(){
        return 0.1;
    }  
}
 
class Milkextends 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 Sugarextends 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());


 

 
总结
 
1.装饰者(Milk)和被装饰者(Coffee)必须是一样的类型。目的是装饰者必须取代被装饰者。
2.添加行为:当装饰者和组件组合时,就是在加入新的行为。
 
题外话:
1.利用继承设计子类行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。打个比方,老子想学点功夫,看你小子会太极拳,老子只需要继承你一下 ,老子也就会太极拳了——呵呵,这时老子就变成你儿子了,看来继承是要付出代价的。
 
2.组合,我们可以扩展对象的行为,在运行时动态地进行扩展。利用组合我们可以随时把我们当时设计超类时没有想到的方法加入到对象中,而不用改变现有的代码。打个比方,老子现在没有内力,吸功大法,把和尚,尼姑,道士的内力(行为对象)都吸过来,那在搏斗(运行时)中,老子可以随时都能使用不同的内力,但也不能胡乱吸内力,否则你就要走火入魔了!
 
3.类应该对扩展开放,对修改关闭。如果我们每个部分都用装饰者模式进行设计,那么对于整个框架来说有点浪费,而且你也加大了代码的难度。那什么时候使用这种模式呢?我们一般用于经常改变的地方。那我们又怎么知道哪些是经常改变的地方呢?这个就需要我们的经验和你对所处行业的了解。建议大家平时多看点例子。
 
4.装饰模式为设计注入弹性,但同时会在设计中加入大量的小类,这偶尔会导致别人不容易了解这种设计。
 
5.在使用装饰者模式的时候,对插入的的装饰者要特别小心。因为装饰者模式依赖某种特定的类型(Beverage)。
 
6.要想很好的使用装饰者模式,我们还要配合使用工厂模式和生成器模式,但今天只说装饰者模式。要想知道更多,请听下回分解。
 

 

参考文献:《head first 设计模式》
顶 3踩 0收藏
文章评论
    发表评论

    个人资料

    • 昵称: 小蜜锋
    • 等级: 高级设计师
    • 积分: 7088
    • 代码: 757 个
    • 文章: 360 篇
    • 随想: 211 条
    • 访问: 1263 次
    • 关注

    标签

    设计模式(4)java(9)命名规范(2)广告创意(1)愤怒的小鸟(1)游戏(5)jsp(1)配置(1)Surface(1)windows(1)javabean(1)设计方法(1)开发工具(2)web(4)大数据(2)GPU(1)硬盘(1)内部结构(1)黑客(1)窃取(1)编码(1)解决方法(1)php(28)mysql(9)数据库备份(1)数据库还原(1)命令(2)数据库(1)安装(1)2012(2)世界末日(3)仙剑5前传(1)默哀(1)电源(1)女生(1)装饰器模式(2)古剑奇谭(1)电脑桌(1)史上最牛(1)编程语言(2)小米(3)电视机顶盒(1)营销策略(1)Android(8)手势(1)诺亚方舟(1)Eclipse(1)汽车(1)操作系统(1)软件(1)互联网(5)大事记(1)设计师(2)壁纸(1)古剑奇谭2(1)古剑奇谭网络版(1)云计算(2)服务器(1)框架(2)Socket(1)jquery(1)构造函数执行顺序(1)火车票(1)3D(1)数据中心(2)正则表达式(2)Web前端(1)开发框架(1)系统瘫痪(1)12306(2)cpu(1)javascript(2)开发日记(15)体育馆管理系统(15)网页设计(1)CSS3(3)腾讯(3)小游戏(1)interface(1)平板(2)面试(2)设计(5)摄影(2)数据挖掘(1)钢琴谱(1)情人节(1)陈欧体(1)程序员(3)漫画(1)UserAgent(1)iPhone(2)NoSQL(1)ui(9)越狱(1)指南(1)abstract(1)css(3)git(2)八核(2)三星(1)linux(11)数据类型(1)html5(2)UML(2)perftools(1)创意(1)logo(1)色谱(1)响应式(5)Metro(2)虚拟机(1)jvm(1)垃圾回收(1)left(1)join(1)连接查询(1)溯源系统(1)Override(1)SAE(2)WordPress(1)指针(1)链表(1)系统分析师(1)中间件(1)corba(1)static(1)无线(1)监控(1)iPad(1)Apache(2)比特币(2)命名规则(1)手机支付(1)curl(3)笔记(1)导航(1)thinkphp(1)异常导致本地路径泄漏(1)web设计(1)网络安全(1)诗句(1)4K对齐(1)代码库(1)色彩(1)动画片(1)struts2(3)漏洞(5)确认框(1)心情驿站(1)ArscEditor(1)resources.(1)apktool(1)AppKey(1)新浪微博(1)app(5)广告(3)赚钱(1)响应式布局(1)html(1)淘宝(2)微信(1)重构(5)缓存(1)破解(1)后门(1)七夕(1)SEO(2)概念设计(1)面向对象(1)bootstrap(1)性能(2)优化(1)iis(1)爬虫(1)采集(1)算法(2)文本相似度(2)cto(1)js(1)fsockopen(1)扁平化设计(2)网页(1)心情(7)小米电视(1)开箱(1)励志(2)招聘(3)命名(1)notepad++(1)python(1)配色(3)扁平化(4)ps(2)搞笑(2)创业(3)渲染(1)电影(1)模板(1)微博(1)企业家(1)公司(1)总结(1)前端(1)运营(1)变形(1)svn(4)教程(3)搜狗(1)泄密(1)双11(1)天猫(1)UC(1)启动界面(1)光棍节(1)双十一(2)物流(1)备份(1)更新(1)插入(1)插件(2)jsTree(1)(1)海量数据(1)分辨率(1)草图(1)手绘(1)速度(1)文本处理(1)实习(1)感想(1)文件(1)简历(1)65.49.2.17(1)yum(1)解决办法(1)阿里云(2)推广(1)来往(1)春运(1)LBS(1)gb2312(1)utf-8(1)log4j(1)详解(1)收购(1)私服(1)TortoiseGi(1)post(1)异常(2)flappyBird(1)应用创新大赛(1)宙斯杯(1)学习方法(1)xp(1)退役(1)安全(1)技术贴(1)flash(1)刷机(1)京东(1)电商(1)Tomcat(1)JDK(1)免费(1)长投影(1)图标(1)Photoshop(1)云端集成开发环境(1)软件开发(1)可视化(1)工具(2)OpenSSL(1)Heartbleed(1)vsftp(1)中国知网(1)学术论文(1)免费下载(1)开发(1)手册(1)速查表(1)追随战略(1)sdk(1)文章(1)发布(1)文件管理(1)沙画(1)动效(2)原型(1)感悟人生(1)哲理(1)Bash(1)类图(1)知识管理(1)Console(1)调试命令(1)rpm(1)报错(1)挂载(1)数据盘(1)云主机(1)产品经理(1)原型设计(1)mql4(1)mt4(1)ea(1)程序化交易(1)CURLOPT_PO(1)阿里云​(1)CentOS6(2)OpenSSH(1)漏洞修复(2)升级(1)安骑士(1)链克(1)

    站长推荐