博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python设计模式-装饰器模式
阅读量:6701 次
发布时间:2019-06-25

本文共 2838 字,大约阅读时间需要 9 分钟。

装饰器模式

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

代码示例

#coding:utf-8#装饰器模式class Beverage():   name = ""   price = 0.0   type = "BEVERAGE"   def getPrice(self):       return self.price   def setPrice(self,price):       self.price = price   def getName(self):       return self.nameclass coke(Beverage):   def __init__(self):       self.name = "coke"       self.price = 4.0class milk(Beverage):   def __init__(self):       self.name = "milk"       self.price = 5.0class drinkDecorator():   def getName(self):       pass   def getPrice(self):       passclass iceDecorator(drinkDecorator):   def __init__(self,Beverage):       self.beverage = Beverage   def getName(self):       return self.beverage.getName() + "  + ice"   def getPrice(self):       return self.beverage.getPrice() + 0.4class sugarDecorator(drinkDecorator):   def __init__(self,Beverage):       self.beverage = Beverage   def getName(self):       return  self.beverage.getName() + "  + sugar"   def getPrice(self):       return self.beverage.getPrice() + 0.8if __name__ == "__main__":   milk1 = milk()   print(milk1.getPrice(),milk1.getName())   iceMilk = iceDecorator(milk1)   print(iceMilk.getPrice(),iceMilk.getName())   cofe1 = coke()   print(cofe1.getPrice(),cofe1.getName())   sugarCofe = sugarDecorator(cofe1)   print(sugarCofe.getPrice(),sugarCofe.getName())复制代码

代码解读

该例子基于的需求:客户点饮料系统,在用户下单的过程中,可以对饮料进行相应的定制。

1、先定义了Beverage类,所有的饮料都是由该类继承而来;

2、定义drinkDecorator类,所有需要新增的功能都是由该类继承而来;

3、定义了iceDecorator类,对所点的饮料进行加冰,并且加冰后价格也需要增加;定义了sugarDecorator类,对所点的饮料进行加糖,并且加糖后价格也需要增加。

4、在客户端调用时,先生成milk1实例,然后在对milk1加冰的过程中,在iceDecorator初始化的时候就将milk1实例传入,在调用getName和getPrice时,调用milk1实例的方法后,接着处理milk1方法返回的结果,从而达到动态的更改getName和getPrice方法。

装饰器模式应用场景: 需要扩展、增强或者减弱一个类的功能。

优点

1、装饰器模式时继承方式的一个替代方案,可以轻量级的扩展被装饰对象的功能; 2、Python的装饰器模式是实现AOP的一种方式,便于相同操作位于不同调用为止的统一管理。

缺点

1、多层装饰器的调试和维护较困难。

Python装饰器模式的通用代码

def drugPrice(func):   def wrapper(self,*args,**kwargs):       print(self,args,kwargs)       self.price += 2       return func(self,*args,**kwargs)   return wrapperclass Food():   def __init__(self):       self.price = 1   @drugPrice   def getPrice(self):       return self.priceif __name__ == "__main__":   f = Food()   print(f.getPrice())复制代码

**python 中的装饰器编写过程: **

先定义装饰器函数

def drugPrice(func):   def wrapper(self,*args,**kwargs):       print(self,args,kwargs)       self.price += 2       return func(self,*args,**kwargs)   return wrapper复制代码

该函数的调用过程如下: 当调用drugPrice(func)函数时,返回的是wrapper函数,该函数是func(self,*args,**kwargs),在wrapper(self,*args,**kwargs)的时候,就是调用的func(self,*args,**kwargs)函数,只不过此时还执行了print(self,args,kwargs);self.price += 2这段语句。

@drugPricedef getPrice(self):   return self.price复制代码

@drugPrice会被Python解析为getPrice=drugPrice(getPrice),此时可以理解为如下的执行顺序

def getPrice(self):   return self.pricegetPrice=drugPrice(getPrice)复制代码

然后调用getPrice()函数就会把装饰器里面的内容执行完成。

识别图中二维码,领取python全套视频资料

转载地址:http://hdwlo.baihongyu.com/

你可能感兴趣的文章
分享一个自己写的table表格排序js插件(高效简洁)
查看>>
三十二、Android上传文件至服务器
查看>>
Silverlight企业应用框架设计【六】自定义系统菜单(使用自己的DataForm)
查看>>
jQuery插件-轻量图片轮换-UISlide
查看>>
在线购物系统权限模块
查看>>
浅谈SQL Server 2008中的Hints(提示)
查看>>
Async Concurrent Queue 2012-04-29 add stop Threads
查看>>
NuGet学习笔记(1) 初识NuGet及快速安装使用
查看>>
PHP笔试题——遍历文件目录
查看>>
Asp.net和C# 函数方法 (2)【转载】
查看>>
百度分享代码(备用)
查看>>
SqlMapConfig.xml 配置
查看>>
wget用法详解
查看>>
在多个线程中避免和发现伪共享
查看>>
[Ubuntu] Ubuntu如何查看cronjob
查看>>
session监听
查看>>
Android Studio更新升级方法
查看>>
virtualbox主机与虚拟机互访,虚拟机上网
查看>>
ios相关手册、图表等综合
查看>>
SharpZipLib 文件/文件夹压缩
查看>>