設計模式之命令模式-引導篇及原理


設計模式之命令模式-引導篇及原理java

引導設計模式

司小司又接到了新項目:家電自動化遙控器API項目。ide

項目背景:隨着物聯網的流行以及智能化傢俱普及。一個遙控器能夠管控家裏全部設備(家電等)也很正常了。函數

來源:凱哥Java(kaigejava)學習


document_image_rId9.png

如上圖:假設空心的是關,實心的是開。測試

需求:this

1:給出各個家電(電燈、電視、音響等)的API,須要在這個遙控器接口中,對接這些API來實現對不一樣家電的控制。spa

2:要求自動化遙控器要擴展性好、維護性好。設計

初版設計:面向對象的傳統思惟orm

說明:0表明電燈對象,1打開音響的音量命令 2:音響音量命令

咱們來看看傳統OO思惟下項目結構:

document_image_rId10.png

說明:

1:電燈和音響SDK相關的API

2:傳統OO思惟下的遙控器

3:遙控器接口

4:測試類

電燈SDKAPI

public class LightAPI {


   /**

    * 電燈所在位置

    */

   private String location "";


   public LightAPI (String location){

       this.location = location;

   }


   /**

    * 開燈效果

    */

   public void On(){

       System.out.println(location +"的燈打開");

   }


   /**

    * 關燈

    */

   public void Off(){

       System.out.println(location+"的燈關了");

   }

}

遙控器接口:

public interface Control {

   public void onButton(int slot);


   public void offButton(int slot);


   public void undoButton();

}


傳統oo對象實現了遙控器接口:

/**

* Created by kaigejava on 2019/8/28.

* 傳統面向對象的遙控器對象

*

*/

public class TraditionOOControl implements Control {


   private LightAPI light;

   private StereoAPI stereo;


   public TraditionOOControl(LightAPI light,StereoAPI stereo){

       this.light = light;

       this.stereo = stereo;

   }

   @Override

   public void onButton(int slot) {

       switch (slot) {

           case 0:

               light.On();

               break;

           case 1:

               stereo.On();

               break;

           case 2:

               int vol = stereo.GetVol();

               if (vol < 11) {

                   stereo.AddVolume(++vol);

               }

               break;

       }


   }


   @Override

   public void offButton(int slot) {

       switch (slot) {

           case 0:

               light.Off();

               break;

           case 1:

               stereo.Off();

               break;

           case 2:

               int vol = stereo.GetVol();

               if (vol > 0) {

                   stereo.downVolume(--vol);

               }

               break;

       }

   }


   @Override

   public void undoButton() {


   }

}


測試類:

public class OOTest {

   public static void main(String[] args) {

       Control ctl;

       LightAPI light = new LightAPI("臥室");

       StereoAPI stereo = new StereoAPI();

       ctl = new TraditionOOControl(light, stereo);


       ctl.onButton(0);

       ctl.offButton(0);

       ctl.onButton(1);

       ctl.onButton(2);

       ctl.offButton(2);


       ctl.offButton(1);

   }

}


運行結果:

document_image_rId11.png

這樣來看,貌似能夠了。咱們在來看看這樣作又什麼很差。

假設如今又有了新需求,須要對接一個掃地機器人(相信你們知道,如今掃地機器人不少家庭都在用了吧)。這個需求來了,咱們應該怎麼作呢 ?

須要修改的地方:

1:SDK確定須要新增長機器人對於的類

2:咱們在TraditionControl類中也須要添加機器人的屬性,而且在有參構造函數、OnButton方法OffButton方法中都有作對應的調整。

感受真個TraditionControl對象都被修改了。這樣還只是添加了一個。若是再過兩天又須要添加一個智能音響或者其餘的。一樣的修改還須要再來一遍。這樣雖然功能是能實現,可是再擴展性和維護性上就很差了。就不符合人家客戶的需求了。

綜上所述,司小司決定不使用傳統的OO思想來實現了。

咱們來分析,SDK和遙控器之間,是經過一個一個按鈕(命令)進行鏈接了。那麼,有沒有一種更好的方案來實現呢?司小司通過調研發現,命令模式就很適合這種場景了。

咱們來看看命令模式。

命令模式原理

咱們先來看看命令模式原理類圖,以下圖:

document_image_rId12.png

原理類圖說明:

控制器(Invoker)裏面有個命令接口(Command),經過控制器裏面的命令接口調用實現該接口的類(ConcreteCommand),進而來控制,具體對象(Receiver)執行

命令模式:

簡單理解:就是將咱們的命令抽取成一個對象,而後將這個對象放到咱們控制器裏面。經過控制器來調用命令對象的實際方法。

定義:

將請求、命令、動做等封裝成對象,這樣可讓項目使用這些對象參數化其餘對象。進而達到命令的請求者和執行者進行解耦。

在知道命令模式原理以後,咱們再來從新設計遙控器項目的類圖,就以下了:

document_image_rId13.png

類圖說明:

Control:遙控器對象

Command:命令接口

LigthXXX:電燈對象相關命令對象

StereoXXX:音響對象相關命令對象

Light:電燈對象

Stereo:音響對象

好了,咱們通過分析,使用命令模式對項目進行了設計。那麼接下來,咱們就使用代碼來實現吧。歡迎接着學習下一篇。再下一篇中,咱們將經過代碼來實現命令模式下的遙控器項目。

凱哥我的博客:www.kaigejava.com

相關文章
相關標籤/搜索