基本描述:
装饰器模式为一种常见的OO模式,该模式的核心思想为:动态的为对象增加或删除功能。
应用场景:
可能大多数情况,学习了设计模式后却不知到在哪种环境下该使用这种设计模式,一大堆模式需要在工作中不断总结才能掌握牢靠,为了避免脱离实际泛泛而谈,一下给出装饰器(Decorator)模式的两个应用场景。
1. 咖啡店模型: 咖啡店有很多种原生咖啡,例如:拿铁咖啡,摩卡咖啡..N种。另外还包括一些加工,例如:加浓,加马鞭草,加香草,加牛奶,和无咖啡因类型咖啡,加冰..M种。如何需要为不同原生咖啡和不同加工的组合使用一般继承的方式各定义一种类型,则至少需要N*M个不同的类,且加入不同的类型后程序要又要进行疯狂编程来完成此模型,这时候就应该使用装饰器模式来完成此类软件建模。
2.疯狂坦克:小的时候玩过坦克大战,在红白机上的儿童游戏,在坦克对战的过程中,可以吃到不同的物品来增加相应得功能。基本坦克只有一种,加工包括:加攻击,加防御,等等。这种情况下基本坦克则为基本类型,加攻击防御则为其装饰,也能用装饰器模式来很好的完成建模。
模式要点:
该模式的应用环境特征总结为:1.有一部分基础类型;2.有一部分对基础类型的修饰。这就是把这种模式命名为装饰器模式的原因。
实例分析:
下文以咖啡店模式为例讲解装饰器(Decorator)模式,本例出至《Thinking In Python 》第四章- Decorators: 动态类型选择。
未使用装饰器模式建模:
class CafeNate: #拿铁咖啡
def __init__(self):
self.cost=3.00;
def getCost(self):
return self.cost;
class CafeNateMilk: #摩卡加牛奶
def __init__(self):
self.cost=3.20;
def getCost(self):
return self.cost;
class CafeNateVanilla: #摩卡加香草
def __init__(self):
self.cost=3.30;
def getCost(self):
return self.cost;
class CafeNateDecaf: #无咖啡因摩卡
def __init__(self):
self.cost=3.50;
def getCost(self):
return self.cost;
class CafeNateIce: #加冰摩卡.
def __init__(self):
self.cost=3.80;
def getCost(self):
return self.cost;
class CafeMocha: #摩卡咖啡
pass
class CafeMochaMilk:
pass
class CafeMochaVanilla:
pass
class CafeMochaIce:
pass
可以见得,建模太过冗余。
使用装饰器模式建模过程。
- 首先,装饰之后的咖啡依然是咖啡,所以装饰器和原生类应具有相同的接口。
- 原生类型可以和装饰类型自由组合成不同的咖啡类型,该过程应在运行时动态完成。
使用装饰器模式实力代码如下:
a. 定义抽象接口类型:
class DrinkComponent: #咖啡抽象接口类.
def getDescription(self):
return self.__class__.__name__;
def getTotalCost(self):
return self.__class__.cost;
b. 定义基础类型:
class CafeMocha(DrinkComponent):
cost=2.0;
class CafeNate(DrinkComponent):
cost=0.0;
#装饰器基类.所有的装饰器从其派生。
class Decorator(DrinkComponent):
def __init__(self,drinkComponent):
self.component=drinkComponent;
def getTotalCost(self):
return self.component.getTotalCost()+ \
DrinkComponent.getTotalCost(self);
def getDescription(self):
return self.component.getDescription()+ \
DrinkComponent.getDescription(self);
c.细化各种装饰器:
#无咖啡因
class Decaf(Decorator):
cost=0.0;
def __init__(self,drinkComponent):
Decorator.__init__(self,drinkComponent );
#加马鞭草
class Whipped(Decorator):
cost=2.0;
def __init__(self,drinkComponent):
Decorator.__init__(self,drinkComponent );
#加牛奶
class Milked(Decorator):
cost=2.0;
def __init__(self,drinkComponent):
Decorator.__init__(self,drinkComponent );
d.使用代码如下:
cappuccino=Whipped( Decaf(CafeNate()) ); #建立无咖啡因且加马鞭草的拿铁咖啡。
print cappuccino.getDescription();
以上过程即为装饰器(Decorator)模式的常见运用。