《Head First》中提到 ,装饰者模式是用来避免类数量爆炸、设计死板,以及基类加入的新功能并不适用于所
有的子类的问题。
书中讲的例子是星巴克的咖啡,咖啡是一种饮料,一杯饮料可以加入不同的调料,也可以混合多种调料,加入不同的调料,需要调整不同的价格。
饮料 | 调料 |
深焙咖啡(DarkRoast) | 摩卡(Mocha) |
| 奶泡(Whip) |
看python代码:
ubuntu@yee:/tmp/beverage$ vim beveragebase.py
#!/usr/bin/python
#-*- coding:utf8 -*-
#饮料基类
class Beverage(object):
description = "Normal Beverage"
def getDescription(self):
return self.description
def cost(self):
pass
#调料修饰者类
class CondimentDecorator(Beverage):
def getDescription(self):
pass
ubuntu@yee:/tmp/beverage$ vim beverage.py
#!/usr/bin/python
#-*- coding:utf8 -*-
from beveragebase import Beverage,CondimentDecorator
class Espresso(Beverage):
def __init__(self):
super(Espresso,self).__init__()
self.description = "Espresso"
def getDescription(self):
return self.description
def cost(self):
return 1.99
class HouseBlend(Beverage):
def __init__(self):
super(HouseBlend,self).__init__()
self.description = 'House Blend Coffee'
def getDescription(self):
return self.description
def cost(self):
return 0.89
ubuntu@yee:/tmp/beverage$ vim condimentdecorator.py
#!/usr/bin/python
#-*- coding:utf8 -*-
from beveragebase import CondimentDecorator,Beverage
class Mocha(CondimentDecorator):
def __init__(self,beverage):
self.beverage = beverage
def getDescription(self):
return self.beverage.getDescription() + ",Mocha"
def cost(self):
return 0.20 + self.beverage.cost()
class Whip(CondimentDecorator):
def __init__(self,beverage):
self.beverage = beverage
def getDescription(self):
return self.beverage.getDescription() + ",Whip"
def cost(self):
return 0.33 + self.beverage.cost()
ubuntu@yee:/tmp/beverage$ vim main.py
#!/usr/bin/python
#-*- coding:utf8 -*-
from beveragebase import Beverage ,CondimentDecorator
from beverage import Espresso,HouseBlend
from condimentdecorator import Whip,Mocha
#老板,来一杯Espresso
coffee = Espresso()
print("coffee description:" + coffee.getDescription() + " ¥:"+str(coffee.cost()))
#老板,再来一杯加Mocha的
coffee = Mocha(coffee)
print("coffee description:" + coffee.getDescription() + " ¥:"+str(coffee.cost()))
#老板 ,咖啡,要加 Mocha ,混点 Whip
coffee = Whip(coffee)
print("coffee description:" + coffee.getDescription() + " ¥:"+str(coffee.cost()))
输出结果 :
ubuntu@yee:/tmp/beverage$ python main.py
coffee description:Espresso ¥:1.99
coffee description:Espresso,Mocha ¥:2.19
coffee description:Espresso,Mocha,Whip ¥:2.52
实际将代码敲一遍,就可以想出它的逻辑了。 这其实就是组件装载模式,选择一个主体,然后选择不同的组件进行组装。这样的模式更加灵活,更加动态,出现新的组装时,不需要去更改到底层的代码。
设计之初,需要明确什么是主体,什么是组件。