Python设计模式——装饰模式(Decorator)
假如我们需要开发一个程序来展示一个人穿衣服的过程。
#encoding=utf-8
__author__ = 'kevinlu1010@qq.com'
class Person():
def __init__(self,name):
print '%s开始穿衣'%name
def wear_tshirt(self):
print '穿TShirst'
def wear_trouser(self):
print '穿裤子'
def wear_shoe(self):
print '穿T鞋子'
def wear_tie(self):
print '穿领带' if __name__=='__main__':
person=Person('kevin')
person.wear_shoe()
person.wear_tie()
person.wear_trouser()
这样写无疑是最快的,代码最简洁的,但是扩展性比较差,例如客户要求我们增加一个穿袜子的动作,我们就需要修改Person类,但是根据封闭-开发原则中的封闭原则,一个类写完之后是尽量不要修改它的,所以我们就需要另外一种实现方式
#encoding=utf-8
__author__ = 'kevinlu1010@qq.com' from abc import ABCMeta, abstractmethod
class Person():
def __init__(self, name):
print '%s开始穿衣' % name class Finery():
__metaclass__ = ABCMeta
@abstractmethod
def show(self):
pass
class TShirt(Finery):
def show(self):
print '穿TShirst' class Trouser(Finery):
def show(self):
print '穿裤子' class Shoe(Finery):
def show(self):
print '穿鞋子' class Tie(Finery):
def show(self):
print '穿领带' if __name__ == '__main__':
person = Person('kevin')
finerys=[]
finerys.append(TShirt())
finerys.append(Trouser())
finerys.append(Shoe())
finerys.append(Tie())
map(lambda x:x.show(),finerys)
首先定义一个积累Finery,定义一个抽象方法show,然后每一个穿衣动作都写一个类,重写show方法。
如果客户修改需求,我们就新增加一个类就可以了。
装饰模式的做法:
#encoding=utf-8
__author__ = 'kevinlu1010@qq.com' from abc import ABCMeta, abstractmethod class Person():
def __init__(self, name):
self.name = name def decorator(self, component):
self.component = component def show(self):
print '%s开始穿衣' % self.name
self.component.show() class Finery():
def __init__(self):
self.component = None def decorator(self, component):
self.component = component __metaclass__ = ABCMeta @abstractmethod
def show(self):
if self.component:
self.component.show() class TShirt(Finery):
def show(self):
Finery.show(self)
print '穿TShirst' class Trouser(Finery):
def show(self):
Finery.show(self)
print '穿裤子' class Shoe(Finery):
def show(self):
Finery.show(self)
print '穿鞋子' class Tie(Finery):
def show(self):
Finery.show(self)
print '穿领带' if __name__ == '__main__':
person = Person('kevin')
tshirt = TShirt()
trouser = Trouser()
shoe = Shoe()
tie = Tie() trouser.decorator(tshirt)
shoe.decorator(trouser)
tie.decorator(shoe)
person.decorator(tie)
person.show()
每个类都有show方法,衣服类都有decorator方法,利用这个方法,动态地把不同衣服的show方法装饰到person这个类上,这样做一方面可以令person类更为精简,因为在实际应用中Person类可能会有很多方法,而穿衣服这个需求只是其中一个,另一方面是,增加Person类的可扩展性,例如如果Person类已经写好了,现在新的需求需要在某一次调用Person类的show方法的时候增加穿衣服的功能,这种模式就能很好地实现了。
Python设计模式——装饰模式(Decorator)的更多相关文章
- 设计模式 装饰模式(Decorator)
设计模式 装饰模式(Decorator) @author ixenos 装饰模式是什么 1.装饰模式以对客户端透明的方式对象的功能,是继承关系的一个替代方案,但装饰模式可以在不创造更多子类的情况下,对 ...
- 设计模式-装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活
- [工作中的设计模式]装饰模式decorator
一.模式解析 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的要点主要是: 1.需要对已有对象扩展新的功能,又不希望改变原有对 ...
- 设计模式——装饰模式(Decorator Pattern)
装饰模式:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. UML图: 模型类: Component类: package com.cnblog.clarck; /** ...
- 大话设计模式Python实现-装饰模式
装饰模式(Decorator Pattern):动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. 下面是一个给人穿衣服的过程,使用装饰模式: #!/usr/bin/en ...
- 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)
原文:乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) 作者:weba ...
- 设计模式系列之装饰模式(Decorator Pattern)——扩展系统功能
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 深入浅出设计模式——装饰模式(Decorator Pattern)
模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是静 ...
- 二十四种设计模式:装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern) 介绍动态地给一个对象添加一些额外的职责.就扩展功能而言,它比生成子类方式更为灵活.示例有一个Message实体类,某个对象对它的操作有Insert()和 ...
随机推荐
- 用java开发的网站或者程序
中国移动的官网即其相关业务系统 阿里巴巴.淘宝网 58同城是java做的后台 铁道部12306 腾讯的拍拍网等 各大银行的交互应用系统,比如有的信用卡网银 另外,Android手机的大部分应用,其他智 ...
- FBReaderJ 编译Jni
最近要做一个电子书项目用到FBReaderJ 第一步,也是最难的一步,要编译他的Jni 文件,对于android开发还是小白的我,只能说难!好难!非常难!,于是乎百度了一下,找到几篇有价值性的文章 第 ...
- 如何去除掉inline-block元素之间的默认间距
前几天写一个页面 div{width:900px;} div li{ display:inline-block; width:300px;} <ul> <li></li& ...
- Windows系统下用命令行编译C/C++程序过程总结
转自:http://www.cnblogs.com/caikehe/archive/2013/01/12/2858017.html (1)先用记事本编写如下所示的代码,并另存为hello.cpp,假设 ...
- 转--xcode duplicate symbol问题
遇到引用库重复定义的问题,需要解决. 项目需要,同时引用ZBar和QQ授权登录SDK,由于二者均使用了Base64处理数据,XCode编译时报错: duplicate symbol _base64 ...
- JAVA_Reflection
package com.qf.reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; imp ...
- LLDB调试基本使用
在平时开发中,我们可能需要调试某些东西,比如查看给服务器发请求时传过去的参数,如果不适用LLDB的话我们用的最多的就是通过NSLog方式去打印,但现在我们可以精简这个步骤,那就是使用LLDB调试命令. ...
- 数据结果与算法分析(1)——算法分析
在确定一个算法正确的同时,也要保证算法的有效性.算法分析的最重要的标准时运行时间T(N),运行时间与输入元素个数N有关. 数学基础 T(N) = O(f(N)) 表示T(N ...
- mfc模态对话框
Mfc模态对话框: 创建模态对话框: [模态对话框:具有独占行为,必须由用户完成对当前对话框的响应,才能对本对话框所属的进程进行其他操作] 例如: 我们创建一个加法计算器.点击计算之后,弹出一个对话框 ...
- 轻松学习Ionic (二) 为Android项目集成Crosswalk(更新官方命令行工具)
现在集成crosswalk不用这么麻烦了!官方的命令行工具已经能让我们一步到位,省去很多工作,只需在cmd中进入项目所在目录(不能有中文目录,还得FQ),执行: ionic browser a ...