策略模式
示例:
商场收银软件—营业员根据客户所购买商品的单价和数量,向客户收费。
商场会不定期的举行各种活动,如 满100减30, 满200减70, 打8折, 满100积分10点等。
很容易想到用简单工厂模式实现,如下图是简单工厂模式的UML类关系图。
收费类–父类
class CashSuper:
def AcceptCash(self, money):
pass
正常收费子类
class CashNormal(CashSuper):
def AcceptCash(self, money):
return money
折扣收费子类
class CashRebate(CashSuper):
def __init__(self, discount):
self.discount = discount
def AcceptCash(self, money):
return money * self.discount
返利收费子类
class CashReturn(CashSuper):
def __init__(self,mcondition,mreturn):
self.mcondition = mcondition
self.mreturn = mreturn
def AcceptCash(self, money):
if(money >= self.mcondition):
return money – self.mreturn
else:
return money
收费工厂类—-
class CashFactory:
CashType = {}
CashType[‘1’] = CashNormal()
CashType[‘2’] = CashRebate(0.8)
CashType[‘3’] = CashReturn(500,100)
def GetResult(self, ch):
if ch in CashType:
op = CashType[ch]
return op
客户端主要程序是
if __name__ == ‘__main__’:
money = raw_input(“money is “)
cashtype = raw_input(“cash type is : [1] for Normal, [2] for Rebate, [3] for Return “)
cashf = CashFactory()
cash = cashf.GetCashType(cashtype)
print cash.AcceptCash(money)
虽然工厂模式也能解决这个问题,但是工厂模式只能解决对象的创建问题。由于工厂本身包括了所有的收费方式,打折额度和返利方式可能经常变更,每次维护或扩展都要改动这个工厂,以至于代码需要重新部署。
无论是打折还是返利都是商家的促销策略,用工厂模式创建这些策略对象本身没错,这是这些策略相互替代的变化也同样需要封装。
策略模式
它定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
策略模式分离了对象和其行为,对象根据策略不通,选择组合不同的行为。
用策略模式的UML关系图。
CashContext类
class CashContext:
def __init__(self, csuper): ## 通过构造函数,传入具体的收费策略
self.csuper = csuper
def GetResult(self):
return self.csuper.acceptCash(self, money) ##获得相应收费策略的结果
定义这样纯策略模式的CashContext类对象,会导致要在客户端去决定用哪一种收费策略。我们将策略模式与简单工厂模式结合,将选择收费策略的判断移到CashContext类中。
改进后的CashContext类
class CashContext:
CashStrategys = {}
CashStrategys[‘1’] = CashNormal()
CashStrategys[‘2’] = CashRebate()
CashStrategys[‘3’] = CashReturn()
def __init__(self, cashtype):
if cashtype in CashStrategys:
self.csuper = CashStrategys[cashtype]
def GetResult(self, money):
return self.csuper.acceptCash(self,money)
客户端主要代码:
if __name__ == ‘__main__’:
money = raw_input(“money is “)
cashtype = raw_input(“cash type is : [1] for Normal, [2] for Rebate, [3] for Return “)
csuper = CashContext(cashtype)
cash = csuper.GetResult(money)
print cash
当不同的行为堆砌在一个类中时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的策略类中,可以在使用这些行为的类中消除条件语句。
只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。
原文链接:https://blog.csdn.net/weixin_39617685/article/details/110342522?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165277499316782395367768%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=165277499316782395367768&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~times_rank-6-110342522-null-null.nonecase&utm_term=%E4%BC%98%E6%83%A0
暂无评论内容