設計模式學習命令模式

      網友投稿 771 2022-05-29

      命令模式是什么?

      命令模式是一種行為型模式,它將請求以命令的形式包裹在對象里面,傳遞給調用對象,調用對象尋找匹配該命令的對象,將命令給該對象執行。也就是分為了三步:

      1、命令被包裹在請求對象里,傳遞給調用對象。

      2、調用對象查找匹配該命令(可以處理該命令)的對象,將該命令傳遞給匹配的對象。

      3、該對象執行傳遞給它的命令。

      一般而言,在軟件開發中,行為的請求者和行為的執行者是緊密耦合在一起的,調用關系簡單易懂,但是這樣不容易拓展,有些時候,我們需要記錄、撤銷、重做處理的時候,不易修改。因此我們需要將命令抽象化,封裝起來,不直接調用真正的執行者方法,易于拓展。

      舉個現實中的例子,比如我們去餐廳吃飯:

      點餐(寫好菜單,發起請求) --> 訂單系統處理,生成訂單(創建命令) --> 廚師獲取到訂單,開始做菜(執行命令),在這個過程中我們并沒有直接與廚師交談,不知道那個廚師做,廚師也不知道是哪個顧客需要,只需要按照訂單處理就可以。

      又比如,我們經常使用智能音響,我經常叫它 ”小度小度,幫我打開空調“,”小度小度,幫我打開窗簾“等等,在整個過程中,我發出命令 --> 小度接受到命令,包裝成為請求 --> 讓真正接收命令的對象處理(空調或者窗簾控制器),我沒有手動去操作空調和窗簾,小度也可以接受各種各樣的命令,只要接入它,我都通過它去操作。

      命令模式中的角色

      在命令模式里面,一共存在以下的角色:

      Command(抽象命令):命令有通用的特性,將命令抽象成一個類,不同的命令做不同的實現

      ConcreteCommand(具體命令類):實現抽象命令,做具體的實現

      Receiver(接受者):真正執行命令的對象

      Invoker(調用者/請求者):請求的封裝發送者,它通過命令對象來執行請求,不會直接操作接受者,而是直接關聯命令對象,間接調用到接受者的相關操作。

      Client(客戶端):一般我們在客戶端中創建調用者對象,具體的命令類,去執行命令。

      命令模式的UML圖如下:

      命令模式的實現

      下面我們模擬一下智能音響的場景:

      先創建一個空調對象,也就是Receiver(接受者),它才是真正的操作對象:

      public class AirConditionerReceiver { public void turnOn(){ System.out.println("打開空調..."); } public void turnOff(){ System.out.println("關閉空調..."); } }

      抽象命令類如下:

      public interface Command { void execute(); }

      打開TurnOnCommand以及關閉TurnOffCommand空調的具體實現類:

      public class TurnOnCommand implements Command{ private AirConditionerReceiver airConditionerReceiver; public TurnOnCommand(AirConditionerReceiver airConditionerReceiver) { super(); this.airConditionerReceiver = airConditionerReceiver; } @Override public void execute() { airConditionerReceiver.turnOn(); } } public class TurnOffCommand implements Command{ private AirConditionerReceiver airConditionerReceiver; public TurnOffCommand(AirConditionerReceiver airConditionerReceiver) { super(); this.airConditionerReceiver = airConditionerReceiver; } @Override public void execute() { airConditionerReceiver.turnOff(); } }

      Invoker調用者,/請求者(智能音響):

      public class Invoker { private Command command; public Invoker(Command command) { this.command = command; } public void action(){ System.out.print("小度智能家居為你服務 --> "); command.execute(); } }

      客戶端測試一下:

      public class Client { public static void main(String[] args) { Command command = new TurnOnCommand(new AirConditionerReceiver()); Invoker invoker = new Invoker(command); invoker.action(); Command turnOffCommand = new TurnOffCommand(new AirConditionerReceiver()); Invoker turnOff = new Invoker(turnOffCommand); turnOff.action(); } }

      測試結果如下:

      小度智能家居為你服務 --> 打開空調... 小度智能家居為你服務 --> 關閉空調...

      設計模式之學習命令模式

      通過以上的測試,我們確實通過命令傳遞,就可以操作空調,客戶端也沒有直接關聯空調,如果需要其他操作,那么另外實現一個命令實現類即可,拓展比較方便,不同命令之間不會相互影響。

      命令模式的拓展

      多條命令

      如果我們需要執行多條命令,那么可以考慮在內部維護一個列表,添加之后依次執行即可。

      維護日志

      如果考慮到執行命令的日志,我們則需要將對象序列化保存起來(磁盤上),維護好執行的狀態,在系統故障的時候,可以從斷開的地方繼續執行。

      撤銷

      如果某個命令需要撤銷,那么我們需要在命令的抽象類里面加一個undo()方法,類似于Mysql數據庫的undo操作,執行它即可撤銷操作,當然這個中間過程涉及到了狀態的維護,細節需要具體的命令來實現。(類似于數據庫的事務回滾)

      優缺點

      優點:

      降低系統耦合度

      易于拓展新的命令

      缺點:

      具體命令如果過多,類數量爆炸

      命令模式主要是想讓請求者與真正的接受者解耦合,其實用的伎倆也是加一層(命令層)的操作,有一句話說得好,不是我說的:

      這句話幾乎概括了計算機軟件體系結構的設計要點.整個體系從上到下都是按照嚴格的層級結構設計的,體現了設計的層次感,而不是相互纏繞。個人覺得之所以這樣設計,最根本的原因在于社會分工以及人類大腦思維對于分層體系認知能力比較強,畢竟代碼是不同人寫給不同人讀的。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:springboot +nginx +freemarker 模板的簡單集成
      下一篇:7月7本新書:主角Python+經典教材閃亮登場
      相關文章
      亚洲特级aaaaaa毛片| 亚洲春黄在线观看| 亚洲国产精品日韩av不卡在线| 亚洲激情电影在线| 亚洲宅男天堂a在线| 亚洲国产精品人久久电影| 亚洲欧洲国产综合| 亚洲日产2021三区在线 | 亚洲成人黄色在线观看| 亚洲高清视频免费| 亚洲日韩在线视频| 亚洲AV成人无码天堂| 亚洲色精品VR一区区三区| 亚洲色大成网站www久久九| 亚洲AV无码之国产精品| 国产偷国产偷亚洲高清人| 亚洲AV永久无码精品一区二区国产| 一本久到久久亚洲综合| 亚洲乱码中文字幕手机在线| MM131亚洲国产美女久久| 亚洲精品自在在线观看| 久久精品国产亚洲AV网站 | 久久久久亚洲Av片无码v| 亚洲精品高清国产麻豆专区| 亚洲午夜国产精品无卡| 在线a亚洲老鸭窝天堂av高清| 亚洲国产精品无码久久九九大片| 亚洲a∨国产av综合av下载| 亚洲成A人片在线观看无码3D| 亚洲真人日本在线| 亚洲av永久无码精品古装片| 91亚洲精品第一综合不卡播放| 亚洲欧洲国产成人精品| 亚洲色中文字幕在线播放| 亚洲AV电影天堂男人的天堂| 国产成人精品亚洲| 丁香五月亚洲综合深深爱| 亚洲国产精品嫩草影院在线观看| 在线观看亚洲人成网站| 自拍日韩亚洲一区在线| 在线91精品亚洲网站精品成人|