简介
装饰者(decorator) + 被装饰对象(component) = 装饰者模式
装饰者模式动态的将功能或者属性附加到对象上,若要扩展功能,装饰者模式提供了比继承更有弹性的替代方案。
使用时,需要时一般有以下属性:
- 装饰者与被装饰对象一般具有相同的超类:这样可以保证任何在需要被包装对象的场合,可以用装饰对象来替代
- 可以使用一个或者多个装饰者包装一个对象
- 装饰者可以在被装饰对象的行为之前/后,加上自己的行为
- 被装饰对象可以在任何时候被装饰,包括运行时
以下代码,根据《head first 设计模式》中的java案例使用python进行实现:
简化后的需求:
咖啡是一种饮料,售卖时,需要给其中加不同的配料。不同类型的咖啡由不同的配料组成。
咖啡为被装饰对象,配料为装饰者。要求可以给咖啡类中随意的添加配料
Python代码实现
class Berverage:
"""
共同的基类
"""
descriptions = ""
def cost(self):
raise NotImplementedError
class Espresso(Berverage):
"""
咖啡的类型-浓缩咖啡
"""
def __init__(self):
self.descriptions = "Espresso"
def get_descriptions(self):
return self.descriptions
def cost(self):
return 1.99
class CondimentDecorator(Berverage):
"""
装饰对象的基类
"""
berverage = None
def __init__(self, berverage):
self.berverage = berverage
def get_descriptions(self):
raise NotImplementedError
class Mocha(CondimentDecorator):
"""
装饰类-摩卡
"""
def get_descriptions(self):
return self.berverage.get_descriptions() + ",Mocha"
def cost(self):
return self.berverage.cost() + 0.20
class Whip(CondimentDecorator):
"""
装饰类-奶泡
"""
def get_descriptions(self):
return self.berverage.get_descriptions() + ",Whip"
def cost(self):
return self.berverage.cost() + 0.10
测试代码:
# 使用示例
# 浓缩咖啡
berverage = Espresso()
# 加摩卡
berverage = Mocha(berverage)
# 加奶泡
berverage = Whip(berverage)
desc = berverage.get_descriptions()
price = berverage.cost()
print(desc,"$", price)
输出结果:
Espresso,Mocha,Whip $ 2.29