設計模式-行為型模式的要點/結構/適用範圍
序言
通過這篇文章總結行為型模式的要點、結構和適用範圍。接下來會就具體每一種設計模式進行學習。
行為型模式的分類
職責鏈模式
命令模式
直譯器模式
迭代器模式
中介者模式/調停者模式
備忘錄模式
觀察者模式
狀態模式
策略模式
模板方法模式
訪問者模式
1. 職責鏈模式
- 結構
舉例
喝酒時通過成語接龍決定誰喝酒(馬到成功-功不可沒-沒完沒了)
要點
- 使多個物件都有機會處理請求,從而避免請求的傳送者和接收者之間的耦合關係。將這些物件連成一條鏈,並沿著這條鏈傳遞該請求,知道有一個物件處理它為止。
適用範圍
有多個的物件可以處理一個請求,哪個物件處理該請求執行時刻自動確定。
你想在不明確指定接收者的情況下,向多個物件中的一個提交一個請求。
可處理一個請求的物件集合應被動態指定。
2. 命令模式
- 結構
舉例
開關與電燈(請求傳送者:開關;命令物件:電線,封裝傳送者的請求;接收者:電燈)
上網IE輸入 http地址 傳送命令
要點
把一個請求或者操作封裝到一個物件中。把發出命令的責任和執行命令的責任分割開,委派給不同的物件。命令模式允許請求的一方和傳送的一方獨立開來,使得請求的一方不必知道接收請求的一方的介面,更不必知道請求是怎麼被接收,以及操作是否執行,何時被執行以及是怎麼被執行的。
對請求排隊或記錄請求日誌,以及支援可撤銷的操作。
適用範圍
抽象出待執行的動作以引數化某物件,可用過程語言中的回撥函式表達這種引數化機制。即函式先在某處註冊,而它將在稍後某個需要的時候被呼叫。命令模式是回撥機制的一個面向物件的替代品。
在不同的時刻指定、排列和執行請求。
支援取消操作。
支援修改日誌,這樣系統崩潰時,這些修改可以被重做一遍。
用構建在原語操作上的高層操作構造一個系統。
3. 直譯器模式
- 結構
舉例
編譯原理之編譯器
文言文註釋:一段文言文,將它翻譯成白話文
要點
- 給定一個語言,定義它的文法的一種表示,並定義一個直譯器,這個直譯器使用該表示來解釋語言中的句子。
適用範圍
當有一個語言需要解釋執行,並且你可將該語言中的句子表示為一個抽象語法樹時,可使用直譯器模式。該文法簡單對於複雜的文法,文法的類層次變得龐大而無法管理。此時語法分析程式生成器這樣的工具是更好的選擇。
效率不是一個關鍵問題最高效的直譯器通常不是通過直接解釋語法分析樹實現的,而是首先將它們轉換成另一種形式。
4. 迭代器模式
- 結構
舉例
查詢資料庫,返回結果集(map, list, set)
遍歷一個容器物件時(比如電視機遙控器調臺)
要點
- 提供一種非那個發順序訪問一個聚合物件中各個元素,而又不需暴露該物件的內部表示。
適用範圍
訪問一個聚合物件的內容而無需暴露它的內部表示。
支援對聚合物件的多種遍歷。
為遍歷不同的聚合結構提供一個統一的介面(即支援多型迭代)。
5. 中介者模式
- 結構
舉例
法院和原告,被告的關係
要點
- 用一箇中介物件來封裝一系列的物件互動。中介者使各物件不需要顯示地相互作用,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動。
適用範圍
一組物件以定義良好但是複雜的方式進行通訊。產生的相互依賴關係結構混亂且難以理解。
一個物件引用其他很多物件並且直接與這些物件通訊,導致難以複用該物件。
想定製一個分佈在多個類中的行為,而又不想生成太多的子類。
6. 備忘錄模式
- 結構
舉例
備份系統時使用
要點
在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可以將該物件恢復到原先儲存的狀態。
涉及到角色主要有三個:發起人角色,備忘錄角色和負責人角色。
適用範圍
必須儲存一個物件在某一個時刻的(部分)狀態,這樣以後需要時它才能恢復到先前的狀態。
如果一個用介面來讓其它物件直接得到這些狀態,將會暴露物件的實現細節並破壞物件的封裝性。
7. 觀察者模式
- 結構
舉例
公司郵件系統[email protected]的應用。當公司員工向這個郵箱發郵件時會發給公司的每一個員工。如果設定了Outlook則會及時收到通知。
要點
- 定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新。
適用範圍
當一個抽象模型有兩個方面,其中一個方面依賴於另一個方面。將這二者封裝在獨立的物件中以使它們可以各自獨立地改變和複用。
當對一個物件的改變需要同時改變其他物件,而不知道具體有多少物件有待改變。
當一個物件必須通知其它物件,而它又不能假定其他物件是誰。換言之,你不希望這些物件是緊密耦合的。
8. 狀態模式
- 結構
舉例
遊戲角色的升級
人心情不同時表現不同有不同的行為
編鐘
登入login logout
要點
- 允許一個物件在其內部狀態改變時改變它的行為,物件看起來似乎修改了它的類。
適用範圍
一個物件的行為取決於它的狀態,並且必須在執行時刻根據狀態改變它的行為。
一個操作中含有龐大的多分支的條件語句,且這些分支依賴於該物件的狀態。這個狀態通常用一個或多個列舉常量表示。
- 通常,有多個操作包含這一相同的條件結構,狀態模式將每一個分支放入一個獨立的類中,這使得你可以根據物件自身的情況將物件的狀態作為一個物件,這一物件可以不依賴於其他物件而獨立變化。
9. 策略模式
- 結構
舉例
電影票打折方案
圖書銷售,不同書本折扣演算法
QQ使用外掛。客戶端是人,抽象類是外掛,具體是策略
要點
定義一系列的演算法,把它們一個個封裝起來,並且使它們可相互替換。本模式使得演算法可獨立於使用它的客戶而變化。
策略模式,將演算法的定義和使用分離。
適用範圍
許多相關的類僅僅是行為有異。“策略”提供了一個用多個行為中的一個行為來配置一個類的方法。
需要使用一個演算法的不同變體。例如,你可能會定義一些反映不同的空間/時間權衡的演算法。當這些變體實現為一個演算法的類層次時,可以使用策略模式。
演算法使用客戶不應該知道的資料。可使用策略模式以避免暴露覆雜的、與演算法相關的資料結構。
一個類定義了多種行為,並且這些行為在這個類的操作中以多個條件語句的形式出現。將相關的條件分支移入它們各自的策略類中以代替這些條件語句。
10. 模板方法模式
- 結構
舉例
使用網頁設計時使用的模板架構網頁(骨架) 演算法的各個邏輯系統
銀行不同利息計算模組
要點
- 定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。模板方法模式使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。
適用範圍
一次性實現一個演算法的不變的部分,並將可變的行為留給子類來實現。
各子類中公共的行為應被提取出來並集中到一個公共父類中以避免程式碼重複。
控制子類擴充套件。模板方法只在特定點進行擴充套件。
11. 訪問者模式
- 結構
舉例
賬本:收入和支出。老闆、會計、財務主管檢視賬本的目的和行為不同。
要點
表示一個作用於某物件結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用域這些元素的新操作。
訪問者模式使得增加新的操作很容易,就是增加一個新的訪問者類。
適用範圍
一個類物件結構包含很多類物件,它們有不同的介面,而你想對這些物件實施一些依賴於其具體類的操作。
需要對一個物件結構中的物件進行很多不同的並且不相關的操作,而你想避免讓這些操作“汙染”這些物件的類。
- 訪問者模式使得你可以將相關的操作集中起來定義在一個類中,當該對戲那個結構被很多應用共享時,用訪問者模式讓每個應用僅包含需要用到的操作。
定義物件結構的類很少改變,但經常需要在此結構上定義新的操作。改變物件結構類需要重定義對所有訪問者的介面,這可能需要很大的代價。如果物件結構類經常改變,那麼可能還是在這些類中定義這些操作較好。
Acknowledgements:
http://blog.csdn.net/mr_rog/article/details/41456373
http://blog.csdn.net/LoveLion/article/details/17517213
http://blog.csdn.net/feixiaoxing/article/details/7294900
2017.08.21