如何将这个装饰器改成Python?

时间:2014-11-08 21:05:22

标签: java python decorator

我已经获得了这本书的副本" Head First Design Patterns"并开始用Python编写他们的一些例子。我已经看到了关于Decorator模式的例子,我知道它应该使用组合,但作者提出了一种继承"。借口是装饰器是为了实现类型匹配,而不是用来继承行为"。我在这里有一个问题,我知道Python不是一种打字语言,所以当我从书中的例子(使用Java)时,我得到了这个:

from abc import ABCMeta, abstractmethod

class Beverage:
    __metaClass__=ABCMeta

    def __init__(self):
        self.Description="Beverage desconocida"

    def getDescription(self):
        return self.Description

    @abstractmethod
    def calc(self):
        pass


class CondimentDecorator(Beverage):
    __metaClass__=ABCMeta

    @abstractmethod
    def getDescription(self):
        pass

class Espresso(Beverage):
    def __init__(self):
        self.Description="Espresso"

    def calc(self):
        return 2.5

class Pasado(Beverage):
    def __init__(self):
        self.Description="Roasted coffee"

    def calc(self):
        return 1.5

class Mocha(CondimentDecorator):
    def __init__(self,Beverage):
        self.Beverage=Beverage

    def getDescription(self):
        return self.Beverage.getDescription()+" Mocha "

    def calc(self):
        return 0.5+self.Beverage.calc()

def main():
    Beverage=Espresso()
    print Beverage.getDescription()," cost: ",Beverage.calc()
    Beverage2=Pasado()
    Beverage2=Mocha(Beverage2)
    print Beverage2.getDescription()," cost: ",Beverage2.calc()
    Beverage3=Espresso()
    Beverage3=Mocha(Mocha(Beverage3))
    print Beverage3.getDescription()," cost: ",Beverage3.calc()

我想知道是否上课:

CondimentDecorator(饮料)

做得好,因为只要Python没有类型,我就不需要继承Beverage;我是对的吗?

如果我改变它:

CondimentDecorator(),我的代码仍然有效,但在这种情况下,我想知道它是否有必要拥有它,因为它只有一个抽象方法而且它就是它。

我是否需要更改我的代码以使其与Python OOP编程更加一致?

由于

1 个答案:

答案 0 :(得分:0)

Python没有严格的输入,通常不需要继承或抽象类。装饰器模式需要Decorator-Class,因为它应该定义装饰类的每个方法来调用嵌入式实例的方法。如果你覆盖所有方法,你绝对不需要这个装饰类。这是一个没有继承的版本:

class Espresso(object):
    description="Espresso"

    def calc(self):
        return 2.5

class Pasado(object):
    description="Roasted coffee"

    def calc(self):
        return 1.5

class Mocha(object):
    def __init__(self, beverage):
        self.beverage = beverage

    @property
    def description(self):
        return self.beverage.description+" Mocha"

    def calc(self):
        return 0.5+self.beverage.calc()

def main():
    beverage = Espresso()
    print beverage.description, " cost: ", beverage.calc()
    beverage2 = Pasado()
    beverage2 = Mocha(beverage2)
    print beverage2.description, " cost: ", beverage2.calc()
    beverage3 = Espresso()
    beverage3 = Mocha(Mocha(beverage3))
    print beverage3.description, " cost: ", beverage3.calc()

if __name__ == '__main__':
    main()

另一方面,Python是一种动态语言,您可以编写动态装饰器

class GenericDecorator(object):         def init (self,obj):             self.obj = obj

    def __getattr__(self, name):
        return getattr(self.obj, name)

class Flavored(GenericDecorator):
    """Flavor is for free"""
    def __init__(self, beverage, flavor):
        GenericDecorator.__init__(self, beverage)
        self.flavor = flavor

    @property
    def description(self):
        return self.flavor + '-' + self.obj.description

def main():
    beverage = Espresso()
    beverage = Flavored(beverage, 'Vanilla')
    print beverage.description, " cost: ", beverage.calc()

if __name__ == '__main__':
    main()