5.9 STRATEGY(策略) — 對象行為型模式

1 意圖

定義一系列的算法憋槐,把它們一個個封裝起來,并且使它們可相互替換诈乒。本模式使得算法可獨立于使用它的客戶而變化戏羽。

2 別名

政策(Policy)

3 動機

有許多算法可對一個正文流進行分析。將這些算法硬編進使用它們的類中是不可取的狱掂,其原因如下:

  • 需要換行功能的客戶程序如果直接包含換行算法代碼的話將會變得復(fù)雜演痒,這使得客戶程序龐大并且難以維護, 尤其當(dāng)其需要支持多種換行算法時問題會更加嚴(yán)重。
  • 不同的時候需要不同的算法符欠,我們不想支持我們并不使用的換行算法嫡霞。
  • 當(dāng)換行功能是客戶程序的一個難以分割的成分時 ,增加新的換行算法或改變現(xiàn)有算法將十分困難。
    我們可以定義一些類來封裝不同的換行算法希柿,從而避免這些問題诊沪。一個以這種方法封裝的算法稱為一個策略(Strategy),如下圖:


    image.png

    假設(shè)一個Composition類負責(zé)維護和更新一個正文瀏覽程序中顯示的正文換行曾撤。換行策略不是 Composition類實現(xiàn)的端姚,而是由抽象的Composition類的子類各自獨立地實現(xiàn)的。Composition各個子類實現(xiàn)不同的換行策略:

  • SimpleComposition實現(xiàn)一個簡單的策略挤悉,它一次決定一個換行位置渐裸。
  • TeXComposition實現(xiàn)查找換行位置的TEX算法。這個策略盡量全局地優(yōu)化換行装悲,也就是一次處理一段文字的換行昏鹃;
  • ArrayCompositor實現(xiàn)一個策略, 該策略使得每一行都含有一個固定數(shù)目的項。例如 , 用于對一系列的圖標(biāo)進行分行诀诊。
    Composition維護對Compositor對象的一個引用洞渤。一旦Composition重新格式化它的正文,它就將這個職責(zé)轉(zhuǎn)發(fā)給它的Compositor對象属瓣。Compositor的客戶指定應(yīng)該使用哪一種Compositor的方式是直接將它想要的Compositor裝入Composition中载迄。
4 適用性

當(dāng)存在以下情況時使用Strategy模式:

  • 許多相關(guān)的類僅僅是行為有異÷胀埽“策略”提供了一種用多個行為中的一個行為來配置一個類的方法护昧。
  • 需要使用一個算法的不同變體。例如粗截,你可能會定義一些反映不同的空間 /時間權(quán)衡的算法惋耙。當(dāng)這些變體實現(xiàn)為一個算法的類層次時 [ H O 8 7 ] ,可以使用策略模式。
  • 算法使用客戶不應(yīng)該知道的數(shù)據(jù)≌篱唬可使用策略模式以避免暴露復(fù)雜的遥金、與算法相關(guān)的數(shù)據(jù)結(jié)構(gòu)。
  • 一個類定義了多種行為 , 并且這些行為在這個類的操作中以多個條件語句的形式出現(xiàn)蒜田。將相關(guān)的條件分支移入它們各自的 S t r a t e g y類中以代替這些條件語句。
5 結(jié)構(gòu)
image.png
參與者
  • Strategy(策略选泻,如Compositor)
    ——定義所有支持的算法的公共接口冲粤。 Context使用這個接口來調(diào)用某ConcreteStrategy定義的算法;
  • ConcreteStrategy(具體策略页眯,如SimpleCompositor梯捕,TeXCompositor,ArrayCompositor)
    ——以Strategy接口實現(xiàn)某具體算法
  • Context(上下文窝撵,如Composition)
    ——用一個ConcreteStrategy對象來配置
    ——維護一個對Strategy對象的引用
    ——可定義一個接口來讓Strategy訪問它的數(shù)據(jù)
7 協(xié)作
  • Strategy和Context相互作用以實現(xiàn)選定的算法傀顾。當(dāng)算法被調(diào)用時 , Context可以將該算法所需要的所有數(shù)據(jù)都傳遞給該Strategy÷捣睿或者短曾,Context可以將自身作為一個參數(shù)傳遞給Strategy操作。這就讓Strategy在需要時可以回調(diào)Context赐劣。
  • Context將它的客戶的請求轉(zhuǎn)發(fā)給它的Strategy嫉拐。客戶通常創(chuàng)建并傳遞一個ConcreteStrategy對象給該Context魁兼;這樣婉徘,客戶僅與Context交互。通常有一系列的ConcreteStrategy類可供客戶從中選擇咐汞。
8 效果

Strategy模式有下面的一些優(yōu)點和缺點:

  • 1 相關(guān)算法系列:Strategy類層次為Context定義了一系列的可供重用的算法或行為盖呼。繼承有助于析取出這些算法中的公共功能。
  • 2 一個替代繼承的方法:繼承提供了另一種支持多種算法或行為的方法化撕。你可以直接生成一個Context類的子類几晤,從而給它以不同的行為。但這會將行為硬行編制到Context中侯谁,而將算法的實現(xiàn)與Context的實現(xiàn)混合起來 ,從而使Context難以理解锌仅、難以維護和難以擴展,而且還不能動態(tài)地改變算法墙贱。最后你得到一堆相關(guān)的類 , 它們之間的唯一差別是它們所使用的算法或行為热芹。將算法封裝在獨立的Strategy類中使得你可以獨立于其Context改變它,使它易于切換惨撇、易于理解伊脓、易于擴展。
  • 3 消除了一些條件語句:Strategy模式提供了用條件語句選擇所需的行為以外的另一種選擇。當(dāng)不同的行為堆砌在一個類中時 , 很難避免使用條件語句來選擇合適的行為报腔。將行為封裝在一個個獨立的Strategy類中消除了這些條件語句株搔。
  • 4 實現(xiàn)的選擇:Strategy模式可以提供相同行為的不同實現(xiàn)〈慷辏客戶可以根據(jù)不同時間 /空間權(quán)衡取舍要求從不同策略中進行選擇纤房。
  • 5 客戶必須了解不同的Strategy:本模式有一個潛在的缺點,就是一個客戶要選擇一個合適的Strategy就必須知道這些Strategy到底有何不同翻诉。此時可能不得不向客戶暴露具體的實現(xiàn)問題炮姨。因此僅當(dāng)這些不同行為變體與客戶相關(guān)的行為時 , 才需要使用Strategy模式。
  • 6 Strategy和Context之間的通信開銷碰煌;
  • 7 增加了對象的數(shù)目
9 實現(xiàn)

考慮下面的實現(xiàn)問題:

  • 1 定義 Strategy和Context接口: Strategy和Context接口必須使得ConcreteStrategy能夠有效的訪問它所需要的Context中的任何數(shù)據(jù), 反之亦然舒岸。一種辦法是讓Context將數(shù)據(jù)放在參數(shù)中傳遞給Strategy操作 — 也就是說, 將數(shù)據(jù)發(fā)送給Strategy。這使得Strategy和Context解耦芦圾。但另一方面蛾派,Context可能發(fā)送一些Strategy不需要的數(shù)據(jù);
    另一種辦法是讓Context將自身作為一個參數(shù)傳遞給Strategy, 該Strategy再顯式地向該Context請求數(shù)據(jù)个少『檎В或者,Strategy可以存儲對它的Context的一個引用夜焦,這樣根本不再需要傳遞任何東西典尾。在這兩種情況下,Strategy都可以請求到它所需要的數(shù)據(jù)糊探。但現(xiàn)在Context必須對它的數(shù)據(jù)定義一個更為精細的接口钾埂,這將Strategy和Context更緊密地耦合在一起;
  • 2 將Strategy作為模板參數(shù) 在C + +中科平,可利用模板機制用一個Strategy來配置一個類褥紫。然而這種技術(shù)僅當(dāng)下面條件滿足時才可以使用 (1) 可以在編譯時選擇Strategy (2) 它不需在運行時改變。在這種情況下瞪慧,要被配置的類(如髓考,Context)被定義為以一個Strategy類作為一個參數(shù)的模板類。
  • 3 使Strategy對象成為可選的:如果即使在不使用額外的 Strategy對象的情況下弃酌,Context也還有意義的話氨菇,那么它還可以被簡化。Context在訪問某Strategy前先檢查它是否存在妓湘,如果有查蓉,那么就使用它;如果沒有榜贴,那么Context執(zhí)行缺省的行為豌研。這種方法的好處是客戶根本不需要處理Strategy對象,除非它們不喜歡缺省的行為。

10 代碼示例

github地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鹃共,一起剝皮案震驚了整個濱河市鬼佣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌霜浴,老刑警劉巖晶衷,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異阴孟,居然都是意外死亡房铭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門温眉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人翁狐,你說我怎么就攤上這事类溢。” “怎么了露懒?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵闯冷,是天一觀的道長。 經(jīng)常有香客問我懈词,道長蛇耀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任坎弯,我火速辦了婚禮纺涤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抠忘。我一直安慰自己撩炊,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布崎脉。 她就那樣靜靜地躺著拧咳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪囚灼。 梳的紋絲不亂的頭發(fā)上骆膝,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音灶体,去河邊找鬼阅签。 笑死,一個胖子當(dāng)著我的面吹牛蝎抽,可吹牛的內(nèi)容都是我干的愉择。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼锥涕!你這毒婦竟也來了衷戈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤层坠,失蹤者是張志新(化名)和其女友劉穎殖妇,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體破花,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡谦趣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了座每。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片前鹅。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖峭梳,靈堂內(nèi)的尸體忽然破棺而出舰绘,到底是詐尸還是另有隱情,我是刑警寧澤葱椭,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布捂寿,位于F島的核電站,受9級特大地震影響孵运,放射性物質(zhì)發(fā)生泄漏秦陋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一治笨、第九天 我趴在偏房一處隱蔽的房頂上張望驳概。 院中可真熱鬧,春花似錦旷赖、人聲如沸抡句。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽待榔。三九已至,卻和暖如春流济,著一層夾襖步出監(jiān)牢的瞬間锐锣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工绳瘟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留雕憔,地道東北人。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓糖声,卻偏偏與公主長得像斤彼,于是被迫代替她去往敵國和親分瘦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351

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

  • 1 場景問題# 1.1 報價管理## 向客戶報價琉苇,對于銷售部門的人來講嘲玫,這是一個非常重大、非常復(fù)雜的問題并扇,對不同的...
    七寸知架構(gòu)閱讀 5,070評論 9 62
  • 1.問題例1:一個菜單功能能夠根據(jù)用戶的“皮膚”首選項來決定是否采用水平的還是垂直的排列形式去团。同事可以靈活增加菜單...
    小飛豬閱讀 360評論 0 0
  • 1 場景問題 1.1 報價管理 向客戶報價,對于銷售部門的人來講穷蛹,這是一個非常重大土陪、非常復(fù)雜的問題,對不同的客戶要...
    4e70992f13e7閱讀 3,080評論 2 16
  • 策略模式(Strategy)屬于對象行為型設(shè)計模式肴熏,主要是定義一系列的算法鬼雀,把這些算法一個個封裝成擁有共同接口的單...
    山的那邊是什么_閱讀 378評論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)蛙吏,斷路器源哩,智...
    卡卡羅2017閱讀 134,638評論 18 139