设计类的原则:对扩展开放,对修改关闭。
提出问题:
星巴克里的咖啡的计算价格的问题。
我们需要计算不同的咖啡,加上不同的糖和奶的价格
(1)按正常的思路
我们可以先定义一个咖啡的基类,然后让别的类,比如moka,等来扩展。
如果遇到加糖,加奶的,我们就重复定义子类。
好处:继承简单,可以理解
不好:
如果牛奶的价格变化,我们需要修改每个类中的牛奶价格。
(2)改进a
我们可以把奶的价格放到基类中。
好处:牛奶价格变化的时候,主类不用修改,只需要修改基类就OK了。
主类中可以指定其是否加牛奶还是糖
不好的地方:调料价格变化,我们需要修改基类中的cost函数
一旦出现新的调料,我们需要添加并修改基类中的代码
有些饮料,这些调料不合适。
(3)改进b
采用装饰者模式
a 拿一个DarkRoast对象
b 以mocha对象装饰它
c 以whip对象装饰它
d 调用cost()方法,并依赖委托(delegate)将调料的价钱加上去
---
装饰者模式,动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案
---
这里先定义一个抽像类CondimentDecorator继承于基类,然后各种milk,whip基于这个类扩展。
这样后右,我们可以自定义我们的咖啡的类型,比如加milk,加whip,或者两个都加。
如果修改的话,也只需要修改milk这个装饰者类的价格,
如果需要增加新的调料,也只需重新定义一个装饰者即可
---------
提出问题:
星巴克里的咖啡的计算价格的问题。
我们需要计算不同的咖啡,加上不同的糖和奶的价格
(1)按正常的思路
我们可以先定义一个咖啡的基类,然后让别的类,比如moka,等来扩展。
如果遇到加糖,加奶的,我们就重复定义子类。
class beverage:
description = ""
def getDescription(self):
print self.description
def cost(self):
pass
class HouseBlend(beverage):
description = "This is HouseBlend"
def __init__(self):
pass
def cost(self):
return 10
class HouseBlendWithMilk(beverage):
description = "This is HouseBlend with milk"
milk_v = 0
def __init__(self):
self.milk_v = 10
def cost(self):
return 10+self.milk_v
if __name__ == "__main__":
coffee = HouseBlend()
coffee.getDescription()
print coffee.cost()
coffee = HouseBlendWithMilk()
coffee.getDescription()
print coffee.cost()
好处:继承简单,可以理解
不好:
如果牛奶的价格变化,我们需要修改每个类中的牛奶价格。
(2)改进a
我们可以把奶的价格放到基类中。
class beverage:
description = ""
milk = False
def setMilk(self,flag):
self.milk = flag
def hasMilk(self):
return self.milk
def getDescription(self):
print self.description
def cost(self):
money=0
if self.milk == True:
money += 10
return money
class HouseBlend(beverage):
description = "This is HouseBlend"
def __init__(self,milk=False):
if milk == True:
self.setMilk(True)
def cost(self):
money = beverage.cost(self)
return 10 + money
if __name__ == "__main__":
coffee1 = HouseBlend()
coffee2 = HouseBlend(milk=True)
print coffee1.cost()
print coffee2.cost()
好处:牛奶价格变化的时候,主类不用修改,只需要修改基类就OK了。
主类中可以指定其是否加牛奶还是糖
不好的地方:调料价格变化,我们需要修改基类中的cost函数
一旦出现新的调料,我们需要添加并修改基类中的代码
有些饮料,这些调料不合适。
(3)改进b
采用装饰者模式
a 拿一个DarkRoast对象
b 以mocha对象装饰它
c 以whip对象装饰它
d 调用cost()方法,并依赖委托(delegate)将调料的价钱加上去
---
装饰者模式,动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案
---
class beverage:
description = ""
def getDescription(self):
print self.description
def cost(self):
pass
class CondimentDecorator(beverage):
def getDescription(self):
pass
def cost(self):
pass
class HouseBlend(beverage):
description = "This is HouseBlend"
def __init__(self):
pass
def cost(self):
return 10
class Milk(CondimentDecorator):
bev = None
def __init__(self,bev):
self.bev = bev
def getDescription(self):
print "Milk"
def cost(self):
return self.bev.cost()+10
class Whip(CondimentDecorator):
bev = None
def __init__(self,bev):
self.bev = bev
def getDescription(self):
print "Whip"
def cost(self):
return self.bev.cost()+20
if __name__ == "__main__":
coffee1 = HouseBlend()
milk = Milk(coffee1)
whip = Whip(milk)
whip.getDescription()
print whip.cost()
这里先定义一个抽像类CondimentDecorator继承于基类,然后各种milk,whip基于这个类扩展。
这样后右,我们可以自定义我们的咖啡的类型,比如加milk,加whip,或者两个都加。
如果修改的话,也只需要修改milk这个装饰者类的价格,
如果需要增加新的调料,也只需重新定义一个装饰者即可
---------