简介:策略模式(Pattern:Strategy)属于行为型模式,是指对一系列的算法定义,并将每一个算法封装起来,而且他们是可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
模式架构
- 抽象策略角色[Strategy]:定义一个公共接口,各种不同的算法以不同的方式实现这个接口。
- 具体策略类[ConcreteStrategy]:实现类抽象策略Strategy定义的接口,包装相关的算法和行为,提供具体的算法实现。
- 上下文角色[Context]:持有一个策略类的引用,最终给客户端使用。
特性
优点
- 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码
- 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。
- 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。
缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
- 策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。
应用场景
- 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
- 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
- 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
代码示例
我们以超市做活动场景来举例子。
- Context:CashContext类,策略与简单工厂结合
- Stragety:CashSuper类,现金收费抽象类
- ContreteStragety:分三个类,CashRebate,CashNormal,CashReturn,实现具体的收费计算方法。
from abc import ABCMeta, abstractmethod
class CashSuper(object):
@abstractmethod
def acceptCash(self):
pass
class CashNormal(CashSuper):
def acceptCash(self, money):
return money
class CashRebate(CashSuper):
def __init__(self, moneyRebate):
self.moneyRebate = moneyRebate
def acceptCash(self, money):
return money * self.moneyRebate
class CashReturn(CashSuper):
def __init__(self, moneyCondition, moneyReturn):
self.moneyCondition = moneyCondition
self.moneyReturn = moneyReturn
def acceptCash(self, money):
if money > self.moneyCondition:
return money - money / self.moneyCondition * self.moneyReturn
class CashContext(object):
def __init__(self, rate):
self.cashSuper = self.getCashSuper(rate)
def getCashSuper(self, rate):
if rate == "正常收费":
return CashNormal()
elif rate == "满1000减100":
return CashReturn(1000, 100)
elif rate == "打8折":
return CashRebate(0.8)
def getResult(self, money):
return self.cashSuper.acceptCash(money)
if __name__ == '__main__':
number = 300
price = 20
cashContext = CashContext("正常收费")
result = cashContext.getResult(number * price)
print("正常收费为:%d" % result)
cashContext = CashContext("打8折")
result = cashContext.getResult(number * price)
print("打折收费为:%d" % result)
cashContext = CashContext("满1000减100")
result = cashContext.getResult(number * price)
print("打折收费为:%d" % result)
每天多努力那么一点点,积少成多
网友评论