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()和 ...
随机推荐
- highcharts js报表工具(报表插件)
highcharts报表工具(报表插件.图表工具) highcharts效果在线演示(可查看源代码): http://www.hcharts.cn/demo/index.php?p=56 Highc ...
- C#_MVC_Repository_CURD_Controller
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- SOAP 及其安全控制--转载
原文地址:http://my.oschina.net/huangyong/blog/287791 目录[-] 1. 基于用户令牌的身份认证 2. 基于数字签名的身份认证 3. SOAP 消息的加密与解 ...
- 去model化开发
前言 去model化是一种框架设计上的做法,其中的model并不是指架构中的model层,套用Casa大神博客中的原文就是: model化就是使用数据对象,去model化就是不使用数据对象. 常见的去 ...
- 使用socket实现FTP程序
#-*- coding:utf-8 -*- import socketserver from module import * class server: def __init__(self,reque ...
- 优化sql,返回行数少情况下,NL比hash快好多
sql如下 select t.id, t.value, tt.sort as sortno from ENGINEERING_TYPE t left join ENGINEERING_TYPE tt ...
- Android之获取联系人
Android入门中,记录学习中的遇到的问题和一些个人总结. 联系人数据库路径为:/data/data/com.android.providers.contacts/database/contacts ...
- Android_SeekBar
xml: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:too ...
- PHP代码实现MySQL读写分离
关于MySQL的读写分离有几种方法:中间件,Mysql驱动层,代码控制 关于中间件和Mysql驱动层实现Mysql读写分离的方法,今天暂不做研究, 这里主要写一点简单的代码来实现由PHP代码控制MyS ...
- [Doc ID 1590988.1]如何清理E-Business Suite的缓存(Apache/iAS, Cabo, Modplsql, Browser, Jinitiator, Java, Portal, WebADI)?
文档内容 目标 解决方案 参考 适用于: Oracle Applications Technology Stack - 版本 11.5.9 到 12.2.2 [发行版 11.5 到 12. ...