設(shè)計(jì)模式(二十一)策略模式(Strategy)

策略.png

思想:策略模式類似于模板方法模式酣胀,一個(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é)果:
# 買菜
# 最新洗菜方式洗菜
# 最新切菜方法切菜
# 炒菜

策略模式:將可變的方法在類的外部定義塌衰,這樣做的好處是增加了方法的可變性诉稍。這就是策略模式的意義。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末最疆,一起剝皮案震驚了整個(gè)濱河市杯巨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌努酸,老刑警劉巖服爷,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡仍源,警方通過查閱死者的電腦和手機(jī)心褐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笼踩,“玉大人逗爹,你說我怎么就攤上這事『坑冢” “怎么了掘而?”我有些...
    開封第一講書人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長匾旭。 經(jīng)常有香客問我镣屹,道長圃郊,這世上最難降的妖魔是什么价涝? 我笑而不...
    開封第一講書人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮持舆,結(jié)果婚禮上色瘩,老公的妹妹穿的比我還像新娘。我一直安慰自己逸寓,他們只是感情好居兆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著竹伸,像睡著了一般泥栖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上勋篓,一...
    開封第一講書人閱讀 49,785評(píng)論 1 290
  • 那天吧享,我揣著相機(jī)與錄音,去河邊找鬼譬嚣。 笑死钢颂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拜银。 我是一名探鬼主播殊鞭,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼尼桶!你這毒婦竟也來了操灿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤泵督,失蹤者是張志新(化名)和其女友劉穎趾盐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谤碳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年溃卡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜒简。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瘸羡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出搓茬,到底是詐尸還是另有隱情犹赖,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布卷仑,位于F島的核電站峻村,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏锡凝。R本人自食惡果不足惜粘昨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窜锯。 院中可真熱鬧张肾,春花似錦、人聲如沸锚扎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽驾孔。三九已至芍秆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間翠勉,已是汗流浹背妖啥。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留眉菱,地道東北人迹栓。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像俭缓,于是被迫代替她去往敵國和親克伊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法华坦,類相關(guān)的語法愿吹,內(nèi)部類的語法,繼承相關(guān)的語法惜姐,異常的語法犁跪,線程的語...
    子非魚_t_閱讀 31,598評(píng)論 18 399
  • 設(shè)計(jì)模式匯總 一椿息、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,922評(píng)論 1 15
  • 設(shè)計(jì)模式基本原則 開放-封閉原則(OCP)坷衍,是說軟件實(shí)體(類寝优、模塊、函數(shù)等等)應(yīng)該可以拓展枫耳,但是不可修改乏矾。開-閉原...
    西山薄涼閱讀 3,775評(píng)論 3 14
  • 番茄鐘是啥,長的什么樣迁杨?先來照個(gè)面哈哈 很普通是不是钻心?學(xué)習(xí)時(shí)間管理和注重學(xué)習(xí)工作效率的都知道它,番茄工作法風(fēng)靡全球...
    朱敏驛站閱讀 197評(píng)論 0 0
  • 小時(shí)候你快樂的肆無忌憚铅协,那是因?yàn)橛袀€(gè)毫無保留為你付出捷沸,毫無條件把你寵成公主的爸爸。無所顧忌的鬧騰狐史,生氣的離家出走痒给,...
    歡曦閱讀 948評(píng)論 1 1