思想:策略模式類似于模板方法模式酣胀,一個(gè)是靜態(tài)控制电湘,一個(gè)是動(dòng)態(tài)控制。模板方法模式是將統(tǒng)一的方法在父類中實(shí)現(xiàn),而將特殊的方法交給對(duì)應(yīng)的子類實(shí)現(xiàn)晶府,在子類中調(diào)用父類方法的同時(shí)也可直接使用子類自身已經(jīng)實(shí)現(xiàn)的方法。策略模式是將可變的方法交給類 的外部指定函數(shù)來實(shí)現(xiàn)矾飞,在調(diào)用時(shí)直接調(diào)用該函數(shù)名稱即可枚冗。下面的案例二和案例三分別是模板方法模式和策略模式,請(qǐng)仔細(xì)查看二者的區(qū)別诞仓。
意圖:
定義一系列的算法,把它們一個(gè)個(gè)封裝起來, 并且使它們可相互替換缤苫。本模式使得算法可獨(dú)立于使用它的客戶而變化。
適用性:
許多相關(guān)的類僅僅是行為有異墅拭』盍幔“策略”提供了一種用多個(gè)行為中的一個(gè)行為來配置一個(gè)類的方法。
需要使用一個(gè)算法的不同變體谍婉。例如舒憾,你可能會(huì)定義一些反映不同的空間/時(shí)間權(quán)衡的算法。當(dāng)這些變體實(shí)現(xiàn)為一個(gè)算法的類層次時(shí) ,可以使用策略模式穗熬。
算法使用客戶不應(yīng)該知道的數(shù)據(jù)镀迂。可使用策略模式以避免暴露復(fù)雜的死陆、與算法相關(guān)的數(shù)據(jù)結(jié)構(gòu)招拙。
一個(gè)類定義了多種行為, 并且這些行為在這個(gè)類的操作中以多個(gè)條件語句的形式出現(xiàn)。將相關(guān)的條件分支移入它們各自的Strategy類中以代替這些條件語句措译。
案例一
class CashSuper:
def AcceptCash(self,money):
return 0
class CashNormal(CashSuper):
def AcceptCash(self,money):
return money
class CashRebate(CashSuper):
discount = 0
def __init__(self,ds):
self.discount = ds
def AcceptCash(self,money):
return money * self.discount
class CashReturn(CashSuper):
total = 0;
ret = 0;
def __init__(self,t,r):
self.total = t
self.ret = r
def AcceptCash(self,money):
if (money>=self.total):
return money - self.ret
else:
return money
class CashContext:
def __init__(self,csuper):
self.cs = csuper
def GetResult(self,money):
return self.cs.AcceptCash(money)
if __name__ == "__main__":
money = input("money:")
strategy = {}
strategy[1] = CashContext(CashNormal())
strategy[2] = CashContext(CashRebate(0.8))
strategy[3] = CashContext(CashReturn(300,100))
ctype = input("type:[1]for normal,[2]for 80% discount [3]for 300 -100.")
if ctype in strategy:
cc = strategy[ctype]
else:
print "Undefine type.Use normal mode."
cc = strategy[1]
print "you will pay:%d" %(cc.GetResult(money))
案例二:模板方法模式别凤,以烹飪流程為例
class Dinner:
def buy(self):
print("買菜")
def wash(self):
pass
def cut(self):
pass
def fire(self):
print("炒菜")
# 流程回顧
def work(self):
self.buy()
self.wash()
self.cut()
self.fire()
# 定義一個(gè)烹飪實(shí)例
dinner=Dinner()
dinner.work()
# 運(yùn)行結(jié)果:
# 買菜
# 炒菜
# 定義一個(gè)子類繼承自烹飪類
class Dinner_child(Dinner):
def wash(self):
print("最新洗菜方式洗菜")
def cut(self):
print("最新切菜方法切菜")
dinner_child=Dinner_child()
dinner_child.work()
# 運(yùn)行結(jié)果:
# 買菜
# 最新洗菜方式洗菜
# 最新切菜方法切菜
# 炒菜
模板方法模式:將統(tǒng)一的方法在父類中實(shí)現(xiàn),可變的方法在子類中實(shí)現(xiàn)领虹,子類依然可以通過父類的方法調(diào)用自己的方法规哪。
案例三:將上述案例使用策略模式進(jìn)行修改
class Dinner:
def buy(self):
print("買菜")
def wash(self):
pass
def cut(self):
pass
def fire(self):
print("炒菜")
# 將洗菜和切菜的方法通過函數(shù)名稱傳遞
def work(self,wash,cut):
self.buy()
wash()
cut()
self.fire()
# 在類的外部,實(shí)現(xiàn)洗菜和切菜的方法
def wash():
print("最新洗菜方式洗菜")
def cut():
print("最新切菜方法切菜")
# 定義一個(gè)烹飪實(shí)例
dinner=Dinner()
dinner.work(wash,cut)
# 運(yùn)行結(jié)果:
# 買菜
# 最新洗菜方式洗菜
# 最新切菜方法切菜
# 炒菜