Python设计模式-装饰器模式

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

转载声明:转载请注明出处,本技术博客是本人原创文章

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> Python设计模式-装饰器模式

点击上方”python宝典”,关注获取python全套视频,

技术文章第一时间送达!

装饰器模式

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

代码示例


#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.name

class coke(Beverage):
    def __init__(self):
        self.name = "coke"
        self.price = 4.0

class milk(Beverage):
    def __init__(self):
        self.name = "milk"
        self.price = 5.0

class drinkDecorator():
    def getName(self):
        pass
    def getPrice(self):
        pass

class 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.4

class 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.8

if __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 wrapper

class Food():
    def __init__(self):
        self.price = 1
    @drugPrice
    def getPrice(self):
        return self.price

if __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这段语句。


@drugPrice
def getPrice(self):
    return self.price

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


def getPrice(self):
    return self.price
getPrice=drugPrice(getPrice)

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

 

Python设计模式-装饰器模式

识别图中二维码,欢迎关注python宝典

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

转载声明:转载请注明出处,本技术博客是本人原创文章

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> Python设计模式-装饰器模式


 上一篇
递归对象的设计模式 递归对象的设计模式
点击上方”python宝典”,关注获取python全套视频, 技术文章第一时间送达! 组合模式1、内容 对于树形结构,当容器对象(如文件夹)的某一个方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员对象(可以是容器对象,也可以是叶子
2021-04-05
下一篇 
python-外观模式 python-外观模式
点击上方”python宝典”,关注获取python全套视频, 技术文章第一时间送达! 外观模式说明外观模式又叫做门面模式。在面向对象程序设计中,解耦是一种推崇的理念。但事实上由于某些系统中过于复杂,从而增加了客户端与子系统之间的耦合度。例如
2021-04-05