一、是什么?作用
1. 命令模式 將“請求”封裝成對象,以使用不同的請求隊列或者日志來參數話其他對象,命令模式亦可以來支持撤銷的操作
2. 將請求封裝成命令對象,請求的具體執行由命令接收者執行;
作用:
命令發送者與命令執行者解耦;
每一個命令都是一個操作
3. 類圖
Invoke(調用者): 調用者負責執行命令
Command(命令接口): 負責將操作封裝成統一的方法
Concreatecommand(命令實現類): 負責將命令真正執行者的操作封裝起來
Receiver(接受者): 命令的真正執行者
二、示例
代碼場景: 廠商提供一個遙控器,遙控器有個按鈕開關,需要你往這個遙控器上加不同的電器,如: 燈、風扇、空調、門
代碼分析: 命令模式將電器的操作請求封裝成對象
燈:命令的真正執行者
/** * 燈 (Receiver) 命令的真正執行者 */ public class Light { public void on() { System.out.println("開燈"); } public void off() { System.out.println("關燈"); } }
命令接口: 上面有個操作的按鈕,當然你也可以添加其他操作,如: undo
/** * 命令接口 */ public interface Command { void execute(); }
將開燈這個請求封裝成命令對象,如果有其他電器的操作,也可以封裝成命令對象
/** * 開燈命令 (LinghtOnCommand )
*/
public class LinghtOnCommand implements Command {
private Light light; // 這里使用委托解耦
public LinghtOnCommand(Light light) { this.light = light; }
@Override
public void execute() { light.on(); }
}
(遙控器)命令調用者:將命令安裝到遙控器上,同時提供按下按鈕,執行該命令的操作
/** * 遙控器 * 命令調用者 invoke */ public class CommandController { private Command solt; public void setCommand(Command command) { solt = command; } /** * 遙控器 按鈕按下 */ public void buttonWasPressed() { solt.execute(); } }
客戶端調用:
/** * 測試客戶端 */ public class MainClient { public static void main(String[] args) { CommandController commandController = new CommandController(); Light light = new Light(); LinghtOnCommand linghtOnCommand = new LinghtOnCommand(light); commandController.setCommand(linghtOnCommand); commandController.buttonWasPressed(); } }
// 控制台顯示
開燈
三、總結
1.小結
- 命令模式將發出請求對象(CommandController )和執行請求對象解耦
- 調用命令對象的execute(), 會使得接受者的動作會被執行
- 命令模式也支持撤銷,做法是實現一個undo命令,返回execute()被執行之前的狀態
2. 命令模式的更多用途:
- 隊列請求: 從隊列中取出一個命令,調用它的execute(),等待調用完成,將命令對象丟棄,再取下一個命令
- 日志請求
- 事務: 撤銷之前的操作
- 線程池
- 。。。