天天看點

指令模式

指令模式關注動作本身,通過将動作封裝成對象實作調用者和底層實作相分離。調用者隻需要簡單的下達指令,然後等待指令完成即可,對底層發生了什麼完全不知情。

指令模式關注動作本身,通過将動作封裝成對象實作調用者和底層實作相分離。調用者隻需要簡單的下達指令,然後等待指令完成即可,對底層發生了什麼完全不知情。關于指令模式一個很直覺的例子就是點餐:當我們點餐時,我們隻用關心将選好的菜品下單,然後等待送餐即可,我們不關心飯菜是怎麼做的,不關心廚師是男是女。

下面通過一個萬能遙控器的例子進一步認識指令模式。

步入物聯網時代,很多家電都可以實作遠端控制,我們想看電視,聽音樂,打掃房間,隻需要按一下遙控器上對應的按鍵,相應的家電就會自動工作。那麼這樣的一款遙控器要怎樣實作呢?現在的場景是,遙控器上的多個按鈕對應多個家電,每個家電都有“開”、“關”兩個指令。當然,最重要的地方在于,遙控器還必須要能夠友善擴充,以後購置新的家電時,隻要加一些按鈕就可以了。

首先定義指令接口,為簡單起見,指令接口裡面隻有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   @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類家電,實際上完全可以對接任意的家電。現在就需要寫個測試類看看遙控器是否正常工作:

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就是家電。

以上就是指令模式的簡單應用,它允許我們将動作封裝成指令對象,然後就可以随心所欲地存儲、傳遞和調用它們了。通過指令對象實作調用者和執行者解耦,兩者之間通過指令對象間接地進行溝通。

上一篇: top指令
下一篇: shell腳本

繼續閱讀