設計模式之命令模式-引導篇及原理java
引導設計模式
司小司又接到了新項目:家電自動化遙控器API項目。ide
項目背景:隨着物聯網的流行以及智能化傢俱普及。一個遙控器能夠管控家裏全部設備(家電等)也很正常了。函數
來源:凱哥Java(kaigejava)學習
如上圖:假設空心的是關,實心的是開。測試
需求:this
1:給出各個家電(電燈、電視、音響等)的API,須要在這個遙控器接口中,對接這些API來實現對不一樣家電的控制。spa
2:要求自動化遙控器要擴展性好、維護性好。設計
初版設計:面向對象的傳統思惟orm
說明:0表明電燈對象,1打開音響的音量命令 2:音響音量命令
咱們來看看傳統OO思惟下項目結構:
說明:
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);
}
}
運行結果:
這樣來看,貌似能夠了。咱們在來看看這樣作又什麼很差。
假設如今又有了新需求,須要對接一個掃地機器人(相信你們知道,如今掃地機器人不少家庭都在用了吧)。這個需求來了,咱們應該怎麼作呢 ?
須要修改的地方:
1:SDK確定須要新增長機器人對於的類
2:咱們在TraditionControl類中也須要添加機器人的屬性,而且在有參構造函數、OnButton方法OffButton方法中都有作對應的調整。
感受真個TraditionControl對象都被修改了。這樣還只是添加了一個。若是再過兩天又須要添加一個智能音響或者其餘的。一樣的修改還須要再來一遍。這樣雖然功能是能實現,可是再擴展性和維護性上就很差了。就不符合人家客戶的需求了。
綜上所述,司小司決定不使用傳統的OO思想來實現了。
咱們來分析,SDK和遙控器之間,是經過一個一個按鈕(命令)進行鏈接了。那麼,有沒有一種更好的方案來實現呢?司小司通過調研發現,命令模式就很適合這種場景了。
咱們來看看命令模式。
命令模式原理
咱們先來看看命令模式原理類圖,以下圖:
原理類圖說明:
控制器(Invoker)裏面有個命令接口(Command),經過控制器裏面的命令接口調用實現該接口的類(ConcreteCommand),進而來控制,具體對象(Receiver)執行
命令模式:
簡單理解:就是將咱們的命令抽取成一個對象,而後將這個對象放到咱們控制器裏面。經過控制器來調用命令對象的實際方法。
定義:
將請求、命令、動做等封裝成對象,這樣可讓項目使用這些對象參數化其餘對象。進而達到命令的請求者和執行者進行解耦。
在知道命令模式原理以後,咱們再來從新設計遙控器項目的類圖,就以下了:
類圖說明:
Control:遙控器對象
Command:命令接口
LigthXXX:電燈對象相關命令對象
StereoXXX:音響對象相關命令對象
Light:電燈對象
Stereo:音響對象
好了,咱們通過分析,使用命令模式對項目進行了設計。那麼接下來,咱們就使用代碼來實現吧。歡迎接着學習下一篇。再下一篇中,咱們將經過代碼來實現命令模式下的遙控器項目。
凱哥我的博客:www.kaigejava.com