设为首页 收藏本站
查看: 1506|回复: 0

[经验分享] Head First 设计模式——装饰器(Decorator Pattern)——Python实现

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-5-6 10:42:29 | 显示全部楼层 |阅读模式
  本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 Unported许可协议进行许可。允许非商业转载,但应注明作者及出处。

作者:liuyuan_jq

2011-06-14


装饰者模式

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


设计原则

类应该对扩展开放,对修改关闭。


装饰者的特点


  • 装饰者和被装饰对象有相同的超类型。
  • 你可以用一个或多个装饰者包装一个对象。
  • 既然装饰者和被装饰对象有相同的超类型,所以在任何需要原始对象(被包装的)的场合,可以用装饰过的对象代替它。
  • 装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。
  • 对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。

StarBuzz星巴兹咖啡
  
问题:因为StarBuzz的咖啡和调料总类很多,且有多种组合形式。如果使用继承的方式,会导致类膨胀且类不易于扩展。

以装饰者构造饮料订单流程


  

  我们要以饮料为主体,然后在运 行时以调料来“装饰”(decorate)饮料。比方说,如果顾客想要摩卡 和奶泡深焙咖啡
  <!--li { list-style: none;  margin: 0; }p { margin: 0; }span.l { color: red; font-weight: bold; }a.mapnode:link {text-decoration: none; color: black; }a.mapnode:visited {text-decoration: none; color: black; }a.mapnode:active {text-decoration: none; color: black; }a.mapnode:hover {text-decoration: none; color: black; background: #eeeee0; }--><!-- ^ Position is not set to relative / absolute here because of Mozilla -->
  拿一个深焙咖啡(DarkRoast)对象

  • 以摩卡(Mocha)对象装饰它
  • 以奶泡(Whip)对象装饰它
  • 调用cost()方法,并依赖委托(delegate)将调料的价钱加上去
源码
  beverage.py
  #!/usr/bin/env python# -*- coding:utf-8 -*-class Beverage(object):"""饮料接口类"""description = "Unknown Beverage"def getDescription(self):return self.descriptiondef cost(self):raise NotImplementedError("abstract Beverage")class Espresso(Beverage):"""浓缩咖啡"""def __init__(self):self.description = "Espresso"def cost(self):return 1.99class DarkRoast(Beverage):"""深焙咖啡"""def __init__(self):self.description = "Dark Roast Coffee"def cost(self):return .99class Decaf(Beverage):"""低咖咖啡"""def __init__(self):description = "Decaf Coffee"def cost(self):return 1.05class HouseBlend(Beverage):"""综合咖啡"""def __init__(self):description = "House Blend Coffee"def cost(self):return .89
  condiment.py
  #!/usr/bin/env python# -*- coding:utf-8 -*-from beverage import Beverageclass CondimentDecorator(Beverage):"""装饰者基类"""def getDescription(self):raise NotImplementedError("abstract CondimentDecorator")class Whip(CondimentDecorator):"""奶泡"""def __init__(self, beverage):self.beverage = beveragedef getDescription(self):return self.beverage.getDescription() + ", Whip"def cost(self):return .10 + self.beverage.cost()class Soy(CondimentDecorator):"""豆浆"""def __init__(self, beverage):self.beverage = beveragedef getDescription(self):return self.beverage.getDescription() + ", Soy"def cost(self):return .15 + self.beverage.cost()class Mocha(CondimentDecorator):"""摩卡"""def __init__(self, beverage):self.beverage = beveragedef getDescription(self):return self.beverage.getDescription() + ", Mocha"def cost(self):return .20 + self.beverage.cost()class Milk(CondimentDecorator):"""牛奶"""def __init__(self, beverage):self.beverage = beveragedef getDescription(self):return self.beverage.getDescription() + ", Milk"def cost(self):return .10 + self.beverage.cost()
测试
  #!/usr/bin/env python# -*- coding:utf-8 -*-from beverage import *from condiment import *# 浓缩咖啡价格beverage = Espresso()print(beverage.getDescription() + " $" + str(beverage.cost()))# 深焙咖啡 + 2份摩卡 + 奶泡beverage2 = DarkRoast()beverage2 = Mocha(beverage2)beverage2 = Mocha(beverage2)beverage2 = Whip(beverage2)print(beverage2.getDescription() + " $" + str(beverage2.cost()))# 综合咖啡 + 豆浆 + 摩卡 + 奶泡beverage3 = HouseBlend()beverage3 = Soy(beverage3)beverage3 = Mocha(beverage3)beverage3 = Whip(beverage3)print(beverage3.getDescription() + " $" + str(beverage3.cost()))
  Espresso $1.99Dark Roast Coffee, Mocha, Mocha, Whip $1.49Unknown Beverage, Soy, Mocha, Whip $1.34

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-373707-1-1.html 上篇帖子: python程序源码,使用tkinter,不要告密哦 下篇帖子: Head First 设计模式——策略模式(Strategy Pattern)——Python实现
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表