装饰者(或修饰)模式(Decorator):
增加一个修饰类包裹原来的类,装饰过的对象可替代原始对象。
原则:
类应该对扩展开放,对修改关闭。
案例:
奶茶店有多种饮料:奶茶、果汁、咖啡;每种饮料可搭配若干配料:珍珠、布丁、牛奶;要能根据顾客的任意搭配下单并计算价钱;
代码:
#!/usr/bin/python
class Beverage:
description = "Unknown Beverage"
def get_description(self):
return self.description
def cost(self):
pass
class CondimentDecorator(Beverage):
def get_description(self):
pass
class MilkyTea(Beverage):
def __init__(self):
self.description = "MilkyTea"
def cost(self):
return 1.99
class FruitJuice(Beverage):
def __init__(self):
self.description = "FruitJuice"
def cost(self):
return 1.80
class Coffee(Beverage):
def __init__(self):
self.description = "Coffee"
def cost(self):
return 2.00
class Pearl(CondimentDecorator):
def __init__(self, beverage):
self.beverage = beverage
def get_description(self):
return self.beverage.get_description() + " + Pearl"
def cost(self):
return 1.50 + self.beverage.cost()
class Pudding(CondimentDecorator):
def __init__(self, beverage):
self.beverage = beverage
def get_description(self):
return self.beverage.get_description() + " + Pudding"
def cost(self):
return 1.60 + self.beverage.cost()
class Milk(CondimentDecorator):
def __init__(self, beverage):
self.beverage = beverage
def get_description(self):
return self.beverage.get_description() + " + Milk"
def cost(self):
return 2.10 + self.beverage.cost()
if __name__ == '__main__':
b = FruitJuice()
print "%s = $%s\n" % (b.get_description(), b.cost())
b = MilkyTea()
b = Pearl(b)
b = Pudding(b)
print "%s = $%s\n" % (b.get_description(), b.cost())
b = Coffee()
b = Pearl(b)
b = Milk(b)
print "%s = $%s\n" % (b.get_description(), b.cost())
输出:
FruitJuice = $1.8
MilkyTea + Pearl + Pudding = $5.09
Coffee + Pearl + Milk = $5.6
参考:
《Head First 设计模式》