假如我们需要开发一个程序来展示一个人穿衣服的过程。

#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)的更多相关文章

  1. 设计模式 装饰模式(Decorator)

    设计模式 装饰模式(Decorator) @author ixenos 装饰模式是什么 1.装饰模式以对客户端透明的方式对象的功能,是继承关系的一个替代方案,但装饰模式可以在不创造更多子类的情况下,对 ...

  2. 设计模式-装饰模式(Decorator Pattern)

    装饰模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活

  3. [工作中的设计模式]装饰模式decorator

    一.模式解析 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的要点主要是: 1.需要对已有对象扩展新的功能,又不希望改变原有对 ...

  4. 设计模式——装饰模式(Decorator Pattern)

    装饰模式:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. UML图: 模型类: Component类: package com.cnblog.clarck; /** ...

  5. 大话设计模式Python实现-装饰模式

    装饰模式(Decorator Pattern):动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. 下面是一个给人穿衣服的过程,使用装饰模式: #!/usr/bin/en ...

  6. 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)

    原文:乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) 作者:weba ...

  7. 设计模式系列之装饰模式(Decorator Pattern)——扩展系统功能

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  8. 深入浅出设计模式——装饰模式(Decorator Pattern)

    模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是静 ...

  9. 二十四种设计模式:装饰模式(Decorator Pattern)

    装饰模式(Decorator Pattern) 介绍动态地给一个对象添加一些额外的职责.就扩展功能而言,它比生成子类方式更为灵活.示例有一个Message实体类,某个对象对它的操作有Insert()和 ...

随机推荐

  1. (原)linux 编译 lwqq

    1.安装工具 apt-get install automake apt-get install autoconf apt-get install libtool apt-get install lib ...

  2. VB.net 利用SerialPort进行读取串口操作

    Imports SystemImports System.IO.Ports Public Class Form1 Private Sub Form1_Load(ByVal sender As Syst ...

  3. Ⅲ.spring的点点滴滴--赋值

    承接上文 对象的赋值(调用方式都一样不再阐述) .net篇(环境为vs2012+Spring.Core.dll v1.31) public class PropertyDemo{ public Sys ...

  4. Bleed Brake Master Cylinder with Intelligent Tester IT2

    When the brake fluid level drops too low in the master cylinder reservoir, air bubbles can get caugh ...

  5. Java基础知识强化之多线程笔记03:进程与线程 和 多线程的意义

    1. 要想了解多线程,必须先了解线程,而要想了解线程,必须先了解进程,因为线程是依赖于进程而存在. 2. 什么是进程? 通过任务管理器我们就看到了进程的存在. 而通过观察,我们发现只有运行的程序才会出 ...

  6. c++下new与delete基础用法

    delete 释放new分配的单个对象指针指向的内存 delete[] 释放new分配的对象数组指针指向的内存那么,按照教科书的理解,我们看下下面的代码: ]; delete a; //方式1 del ...

  7. SQL Server用存储过程新建视图

    CREATE PROCEDURE [dbo].[p_GetV_view]ASBEGIN DECLARE @sqlstr1 varchar(255) DECLARE @sqlstr2 varchar(2 ...

  8. FIO工具常用参数

    name 可能被用于覆盖作业的名称. filename fio 通常基于该作业名称,线程编号,构成一个文件名称和位置.如果您不想让线程之间的共享文件在一个作业或作业.指定文件名都以覆盖默认的. loc ...

  9. delta

    1,安装synplyfy:综合工程,便于学习(模块间的关系,数据流向) 2,安装wps office:  www.wps.com/linux,论坛有安装方法和依赖包处理 3,安装kmplayer: 4 ...

  10. hive外部表自动读取文件夹里的数据

    我们在创建表的时候可以指定external关键字创建外部表,外部表对应的文件存储在location指定的目录下,向该目录添加新文件的同时,该表也会读取到该文件(当然文件格式必须跟表定义的一致),删除外 ...