【設計模式】Java設計模式 – 命令模式
Java設計模式 – 命令模式
😄生命不息,寫作不止
🔥 繼續踏上學習之路,學之分享筆記
👊 總有一天我也能像各位大佬一樣
🏆 一個有夢有戲的人 @怒放吧德德
🌝分享學習心得,歡迎指正,大家一起學習成長!
簡介
命令模式(Command Pattern)是一種數據驅動的設計模式,它屬於行為型模式。請求以命令的形式包裹在對象中,並傳給調用對象。調用對象尋找可以處理該命令的合適的對象,並把該命令傳給相應的對象,該對象執行命令。
———— 菜鳥聯盟
命令模式解析
命令模式會將一個請求封裝為一個介面對象,由各種功能去實現其方法,在詳細命令類中,通過聚合的方式將具體方法進行抽取調用。
UML圖:
命令模式角色和職責
1)、Invoker:調用者角色
2)、Command:命令角色,需要執行的所有命令,(抽象類或介面)
3)、Receiver:命令接受者,知道如何實施執行某個命令
4)、ConcreteCommand:將一個接受對象和一個命令相互綁定,調用具體應操作的方法。
命令模式實例
通過智慧家居的例子來學習命令模式,有一個遙控器,上面集成了好多台設備的開關操作,有燈光、電視等控制按鈕。採用命令模式來管理控制,具體以下一步一步解析。首先看看具體的類圖:
本次的類結構看起來比較複雜,其實原理都是Java面向對象。
本次實驗通過定義命令介面,裡面包含執行的命令,在通過各種各樣設備去實現命令介面及其方法,不同設備的不同操作,如開、關,各種視為一個類,在這個類中實現不同的操作方法,雖然命令不同,但是可以通過聚合的方式,使用命令接受者類中去實現具體的不同方法進行分別調用。最後定義遙控器定義命令組並且為按鈕去綁定相應的實現命令。
程式碼如下,會一步一步解釋。
①、定義命令角色
命令角色可以是介面也可以是抽象類,根據本次的案例設計為介面。
只有一個執行方法。
package com.lyd.demo.command;
/**
* @Author: lyd
* @Description: 介面 - 命令
* @Date: 2022-09-03
*/
public interface Command {
public void execute(); // 執行方法
}
②、定義空命令
定義空命令是為了防止判空
package com.lyd.demo.command;
/**
* @Author: lyd
* @Description: 空命令方法,簡化空判斷
* @Date: 2022-09-03
*/
public class NoCommand implements Command {
@Override
public void execute() {
}
}
③、定義接受者
接收者就是具體的實現方法。
package com.lyd.demo.command.light;
/**
* @Author: lyd
* @Description: 被聚合類,也就是真正細節執行方法
* @Date: 2022-09-03
*/
public class LightReceive {
public void on() {
System.out.println(" 燈光已打開... ");
}
public void off() {
System.out.println(" 燈光已關閉... ");
}
}
④、定義實現類
燈光打開類,通過聚合方式獲取具體實現方法;燈光實現類實現命令介面,實現執行方法(調用聚合類中的打開方法)
package com.lyd.demo.command.light;
import com.lyd.demo.command.Command;
/**
* @Author: lyd
* @Description: 實現類 - 點燈打開類
* @Date: 2022-09-03
*/
public class LightOnCommand implements Command {
// 聚合
LightReceive lightReceive;
public LightOnCommand(LightReceive lightReceive) {
this.lightReceive = lightReceive;
}
@Override
public void execute() { // 燈光打開命令只需要調用燈光開啟的方法
lightReceive.on();
}
}
關閉命令也是如此設置,這裡不粘貼程式碼了
⑤、定義遙控器
因為遙控器有許多設備的開關,定義相應開關按鈕的命令組,通過構造方法去初始化,並把美格爾對象實例化為空命令對象。通過setCommand方法來綁定按鈕和命令,onButton是模擬按下開關時候調用的方法。
package com.lyd.demo.controller;
import com.lyd.demo.command.Command;
import com.lyd.demo.command.NoCommand;
/**
* @Author: lyd
* @Description: 遙控器
* @Date: 2022-09-03
*/
public class RemoteController {
// 開按鈕的命令組
Command[] onCommand;
// 關閉命令組
Command[] offCommand;
public RemoteController() { // 假設有舞台設備,每台設備都是開關命令
onCommand = new Command[5];
offCommand = new Command[5];
// 初始化
for (int i=0; i<5; i++) {
onCommand[i] = new NoCommand();
offCommand[i] = new NoCommand();
}
}
/**
* 給按鈕設置命令
* @param no 編號-代表設備
* @param onCommand - 開命令
* @param offCommand - 關命令
*/
public void setCommand(int no, Command onCommand, Command offCommand) {
this.onCommand[no] = onCommand;
this.offCommand[no] = offCommand;
}
/**
* 按下開按鈕
* @param no 根據編號去調用哪個設備的執行方法
*/
public void onButton(int no) {
onCommand[no].execute();
}
/**
* 按下關按鈕
* @param no 根據編號去調用哪個設備的執行方法
*/
public void offButton(int no) {
offCommand[no].execute();
}
}
⑥、測試
以上介紹只是寫了一種設備,還可以直接添加其他設備,並不需要改動其他類。
結構圖:
程式碼如下:
package com.lyd.demo.test;
import com.lyd.demo.command.light.LightOffCommand;
import com.lyd.demo.command.light.LightOnCommand;
import com.lyd.demo.command.light.LightReceive;
import com.lyd.demo.command.tv.TvOffCommand;
import com.lyd.demo.command.tv.TvOnCommand;
import com.lyd.demo.command.tv.TvReceive;
import com.lyd.demo.controller.RemoteController;
/**
* @Author: lyd
* @Description: 測試類
* @Date: 2022-09-03
*/
public class CommandTest {
public static void main(String[] args) {
// 創建燈光的接受者 - 具體方法類
LightReceive lightReceive = new LightReceive();
// 創建燈光的命令
LightOnCommand lightOnCommand = new LightOnCommand(lightReceive);
LightOffCommand lightOffCommand = new LightOffCommand(lightReceive);
// 創建遙控器
RemoteController remoteController = new RemoteController();
// 綁定命令到相應的按鈕中
remoteController.setCommand(0, lightOnCommand, lightOffCommand); // 綁定
// 測試
System.out.println("按下開燈按鈕》》》》》");
remoteController.onButton(0); // 0 代表是燈光按鈕
System.out.println("按下關燈按鈕》》》》》");
remoteController.offButton(0);
TvReceive tvReceive = new TvReceive();
TvOnCommand tvOnCommand = new TvOnCommand(tvReceive);
TvOffCommand tvOffCommand = new TvOffCommand(tvReceive);
remoteController.setCommand(1, tvOnCommand, tvOffCommand);
System.out.println("按下開啟電視按鈕》》》》》");
remoteController.onButton(1);
System.out.println("按下關閉電視按鈕》》》》》");
remoteController.offButton(1);
}
}
運行結果:
👍創作不易,可能有些語言不是很通暢,如有錯誤請指正,感謝觀看!記得一鍵三連哦!👍
今天的內容看起來並不簡單,但實質上除了設計模式的思路,其實就是Java的面向對象知識,只要肯動手多敲,就容易理解。