命令模式

命令模式關注動做自己,經過將動做封裝成對象實現調用者和底層實現相分離。調用者只須要簡單的下達命令,而後等待命令完成便可,對底層發生了什麼徹底不知情。關於命令模式一個很直觀的例子就是點餐:當咱們點餐時,咱們只用關心將選好的菜品下單,而後等待送餐便可,咱們不關心飯菜是怎麼作的,不關心廚師是男是女。ide

下面經過一個萬能遙控器的例子進一步認識命令模式。測試

步入物聯網時代,不少家電均可以實現遠程控制,咱們想看電視,聽音樂,打掃房間,只須要按一下遙控器上對應的按鍵,相應的家電就會自動工做。那麼這樣的一款遙控器要怎樣實現呢?如今的場景是,遙控器上的多個按鈕對應多個家電,每一個家電都有「開」、「關」兩個命令。固然,最重要的地方在於,遙控器還必需要可以方便擴展,之後購置新的家電時,只要加一些按鈕就能夠了。this

首先定義命令接口,爲簡單起見,命令接口裏面只有execute方法,由於命令就是要被執行的:spa

1 public interface Command {
2   void execute();
3 }

遙控器上的每個按鈕都是一個命令,對應不一樣的電器,因此命令應該有不少種具體類型,假設目前有燈泡、電視、音箱三種家電,電器的定義以下:3d

 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 }

每種電器都有「開」、「關」兩個具體命令,定義以下:code

 1 // 開燈命令
 2 public class LightOnCommand implements Command{
 3   Light light;
 4 
 5   public LightOnCommand(Light light){
 6     this.light = light;
 7   }
 8 
 9   @Override
10   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   @Override
24   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類家電,實際上徹底能夠對接任意的家電。如今就須要寫個測試類看看遙控器是否正常工做:blog

 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 }

輸出以下:接口

打開電燈。。。
關閉電燈。。。
打開電視。。。
關閉電視。。。
打開音箱。。。
關閉音箱。。。

遙控器看起來一塊兒順利。對以上的代碼進行整理,能夠得出命令模式的類圖以下。rem

 

遙控器對應Client,各類家電的開關命令對應ConcreteCommand,Receiver就是家電。

以上就是命令模式的簡單應用,它容許咱們將動做封裝成命令對象,而後就能夠爲所欲爲地存儲、傳遞和調用它們了。經過命令對象實現調用者和執行者解耦,二者之間經過命令對象間接地進行溝通。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息