標簽: 設計模式初涉
描述性文字
本節(jié)講解的是行為型設計模式種的:命令模式烟勋,該模式非常簡單,
就是用于行為請求者與行為實現(xiàn)者的解耦筐付,舉個簡單的例子卵惦,
擺地攤與開店的流程:(例子參考自大話設計模式)
擺地攤:
顧客 --點餐-> 老板 --收到點餐指令-> 制作菜肴
寫成代碼的話:就是顧客中持有對老板的引用,然后執(zhí)行指令的時候
調用老板中制作菜肴的方法瓦戚。這里的請求者直接與實現(xiàn)者進行交互沮尿,
耦合度比較高!
開店:
增加了一個服務員的角色,接收用戶指令畜疾,處理指令赴邻,然后調用老板
進行菜肴制作,中途還可以記錄命令請求啡捶,或者做撤銷命令的操作姥敛。
先解析一波概念,然后再寫一個簡單的例子~
概念相關
模式定義:
將一個請求封裝成一個對象瞎暑,從而是你可用不同的請求對客戶端參數化彤敛,
對請求排隊或記錄請求日志,以及支持可撤銷的操作了赌。
四個角色:
- Command:命令墨榄,聲明具體命令的抽象接口。
- ConcreteCommand:具體命令勿她,接收者對象綁定與一個動作袄秩。
- Receiver:接收者,執(zhí)行與請求相關的操作逢并,具體實現(xiàn)對請求的業(yè)務處理之剧。
- Invoker:調用者,負責調用命令對象執(zhí)行請求筒狠,相關的方法叫做行動方法猪狈。
UML類圖:
![](http://static.zybuluo.com/coder-pig/xndinedn8zevltii9pregu2j/image_1bb30camb12uq1rm4178vfo21igl9.png)
適用場景
- 1.系統(tǒng)需要將請求調用者和請求接收者解耦,使得調用者和接收者不直接交互辩恼。請求
調用者無須知道接收者的存在雇庙,也無須知道接收者是誰,接收者也無須關心何時被調用灶伊。 - 2.系統(tǒng)需要在不同的時間指定請求和執(zhí)行請求疆前。一個命令對象和請求的初始調用者可
以有不同的生命期,換言之聘萨,最初的請求發(fā)出者可能已經不在了竹椒,而命令對象本身仍然
是活動的,可以通過該命令對象去調用請求接收者米辐,而無須關心請求調用者的存在性胸完,
可以通過請求日志文件等機制來具體實現(xiàn)。 - 3.系統(tǒng)需要支持命令的撤銷(Undo)操作和恢復(Redo)操作翘贮。
- 4.系統(tǒng)需要將一組操作組合在一起形成宏命令赊窥。
優(yōu)缺點
優(yōu)點:
- 1.更松散的耦合,請求者無需知道執(zhí)行者是誰狸页,如何執(zhí)行指令锨能。
- 2.更動態(tài)的控制,將請求封裝,可以動態(tài)進行參數化址遇,隊列化熄阻,日志化等操作。
- 3.命令可以復合倔约,即一個命令可以由多個命令組合而成秃殉,又叫宏命令。
- 4.更好的擴展性跺株,因為命令發(fā)起者與執(zhí)行者解耦复濒,擴展新命令,只需實現(xiàn)新的
命令對象乒省,在需要的時候把具體的實現(xiàn)對象傳入到命令對象中,就可以使用這個命令
對象了畦木,已有的實現(xiàn)完全不用變化袖扛。 - 5.為請求的撤銷(Undo)和恢復(Redo)操作提供了一種設計和實現(xiàn)方案。
缺點:
使用命令模式可能會導致某些系統(tǒng)有過多的具體命令類十籍。因為針對每一個對請求
接收者的調用操作都需要設計一個具體命令類蛆封,因此在某些系統(tǒng)中可能需要提供
大量的具體命令類,這將影響命令模式的使用勾栗。
代碼示例
以前寫過一個叫做寶寶電臺的項目惨篱,里面播放控制部分,重構的時候就想著用
命令模式來實現(xiàn)相關控制围俘,后來還是沒時間寫砸讳,這里用命令模式寫個簡單的播
放控制例子吧。
首先創(chuàng)建播放對象界牡,就一個故事名和播放URL的屬性
![](http://static.zybuluo.com/coder-pig/1wlbxwzncmmx1ns50xqjjdp9/image_1bb35edpqn551u1avfl19vq1b0im.png)
然后創(chuàng)建命令執(zhí)行者簿寂,一個音樂播放器,提供設置播放列表宿亡,播放常遂,暫停等方法
![](http://static.zybuluo.com/coder-pig/la34gvd2icvg6buwqeq9kcjl/image_1bb35gkbo4tu1hvh6r91ukd114e13.png)
接著創(chuàng)建抽象命令接口,就一個execute()的方法
![](http://static.zybuluo.com/coder-pig/85hrfta81pgjzwezsgronql2/image_1bb35iis812kl15gghrd1rkc8hr1g.png)
接著繼承這個接口挽荠,寫各種具體命令類克胳,設置列表,播放圈匆,暫停漠另,下一首,上一首
都是照葫蘆畫瓢臭脓,實現(xiàn)execute()方法酗钞,調用執(zhí)行者里面的對應方法而已。
![](http://static.zybuluo.com/coder-pig/2e38amzz8wzw7g36jdjh3ytc/image_1bb35kduamrk2i213c4bvo14ru1t.png)
![](http://static.zybuluo.com/coder-pig/qjbkfq6ncz8p5ivlcfkjy0ls/image_1bb35ktkd1iu7105u1h111dg7lnn2a.png)
![](http://static.zybuluo.com/coder-pig/wqxudvcr72fg633vxj5hkjm9/image_1bb35ldnp169ajc2h74jegf2n.png)
![](http://static.zybuluo.com/coder-pig/2bg5tl3hf5qdaxch6aayzn2z/image_1bb35ltin1pi71p3l1bgd1n6t1iq634.png)
![](http://static.zybuluo.com/coder-pig/wwqbe2pfpzhgz40957hgobgx/image_1bb35mf9s11ga16agate10nhv003h.png)
再接著是請求者類,低啊用命令對象執(zhí)行具體的操作
![](http://static.zybuluo.com/coder-pig/c9lgbwvph6dweh7nvajp3f0w/image_1bb35q38578slajotb1sr0d8p3u.png)
最后客戶端調用
![](http://static.zybuluo.com/coder-pig/4cl7ucd0iis6qmxclwl1a8c8/image_1bb35sou91vlvbcm1o49gum1ptp4o.png)
輸出結果
![](http://static.zybuluo.com/coder-pig/k01klvqzdbhwxjoevv8oobkc/image_1bb35t7qo1ecusm46q91jng1m8e55.png)
嘿嘿砚作,命令模式就那么簡單~
本節(jié)代碼示例
https://github.com/coder-pig/DesignPatternsExample/tree/master/16.Command%20Pattern