命令模式關注動作本身,通過將動作封裝成物件實作呼叫者和底層實作相分離,呼叫者只需要簡單的下達命令,然后等待命令完成即可,對底層發生了什么完全不知情,關于命令模式一個很直觀的例子就是點餐:當我們點餐時,我們只用關心將選好的菜品下單,然后等待送餐即可,我們不關心飯菜是怎么做的,不關心廚師是男是女,
下面通過一個萬能遙控器的例子進一步認識命令模式,
步入物聯網時代,很多家電都可以實作遠程控制,我們想看電視,聽音樂,打掃房間,只需要按一下遙控器上對應的按鍵,相應的家電就會自動作業,那么這樣的一款遙控器要怎樣實作呢?現在的場景是,遙控器上的多個按鈕對應多個家電,每個家電都有“開”、“關”兩個命令,當然,最重要的地方在于,遙控器還必須要能夠方便擴展,以后購置新的家電時,只要加一些按鈕就可以了,
首先定義命令介面,為簡單起見,命令介面里面只有execute方法,因為命令就是要被執行的:
1 public interface Command {2 void execute();3 }
遙控器上的每一個按鈕都是一個命令,對應不同的電器,所以命令應該有很多種具體型別,假設目前有燈泡、電視、音箱三種家電,電器的定義如下:
1 // 燈泡 2 public class Light { 3 public void on(){ 4 System.out.println("打開電燈,,,"); 5 } 6 7 public void off(){ 8 System.out.println("關閉電燈,,,"); 9 }10 }11 12 // 電視13 public class TV {14 public void on(){15 System.out.println("打開電視,,,");16 }17 18 public void off(){19 System.out.println("關閉電視,,,");20 }21 }22 23 // 音箱24 public class LoudspeakerBox {25 public void on(){26 System.out.println("打開音箱,,,");27 }28 29 public void off(){30 System.out.println("關閉音箱,,,");31 }32 }
每種電器都有“開”、“關”兩個具體命令,定義如下:
1 // 開燈命令 2 public class LightOnCommand implements Command{ 3 Light light; 4 5 public LightOnCommand(Light light){ 6 this.light = light; 7 } 8 9 @Override10 public void execute() {11 light.on();12 }13 }14 15 // 關燈命令16 public class LightOffCommand implements Command{17 Light light;18 19 public LightOffCommand(Light light){20 this.light = light;21 }22 23 @Override24 public void execute() {25 light.off();26 }27 }28 29 // 電視和音箱的開關命令與此型別,略去30 ...
現在可以看看遙控器的樣子了:
1 // 遙控器 2 public class RemoteController { 3 Command[] onCommands; 4 Command[] offCommands; 5 6 public RemoteController(int commandSize){ 7 this.onCommands = new Command[commandSize]; 8 this.offCommands = new Command[commandSize]; 9 }10 11 public void setCommand(int i, Command onCommand, Command offCommand){12 onCommands[i] = onCommand;13 offCommands[i] = offCommand;14 }15 16 // 按下開按鈕17 public void onButtonPressed(int i){18 onCommands[i].execute();19 }20 21 // 按下關按鈕22 public void offButtonPressed(int i){23 offCommands[i].execute();24 }25 }
遙控器針對每一種家電設定了兩個開關,按下對應的家電的對應開關,會觸發相應的動作,這里只對接了3類家電,實際上完全可以對接任意的家電,現在就需要寫個測驗類看看遙控器是否正常作業:
1 public class RemoteControllerTest { 2 public static void main(String[] args){ 3 Light light = new Light(); 4 TV tv = new TV(); 5 LoudspeakerBox loudspeakerBox = new LoudspeakerBox(); 6 Command lightOn = new LightOnCommand(light); 7 Command lightOff = new LightOffCommand(light); 8 Command TVOn = new TVOnCommand(tv); 9 Command TVOff = new TVOffCommand(tv);10 Command LoudspeakerBoxOn = new LoudspeakerBoxOnCommand(loudspeakerBox);11 Command LoudspeakerBoxOff = new LoudspeakerBoxOffCommand(loudspeakerBox);12 13 RemoteController remoteController = new RemoteController(3);14 remoteController.setCommand(0, lightOn, lightOff);15 remoteController.setCommand(1, TVOn, TVOff);16 remoteController.setCommand(2, LoudspeakerBoxOn, LoudspeakerBoxOff);17 18 remoteController.onButtonPressed(0);19 remoteController.offButtonPressed(0);20 remoteController.onButtonPressed(1);21 remoteController.offButtonPressed(1);22 remoteController.onButtonPressed(2);23 remoteController.offButtonPressed(2);24 }25 }
輸出如下:
打開電燈,,,關閉電燈,,,打開電視,,,關閉電視,,,打開音箱,,,關閉音箱,,,遙控器看起來一起順利,對以上的代碼進行整理,可以得出命令模式的類圖如下,

遙控器對應Client,各種家電的開關命令對應ConcreteCommand,Receiver就是家電,
以上就是命令模式的簡單應用,它允許我們將動作封裝成命令物件,然后就可以隨心所欲地存盤、傳遞和呼叫它們了,通過命令物件實作呼叫者和執行者解耦,兩者之間通過命令物件間接地進行溝通,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/42108.html
標籤:設計模式
上一篇:設計模式-行為型-模板模式
下一篇:設計模式-行為型-策略模式
