命令模式(Command)的定義
將一個請求封裝為一個對象,從而可用不同的請求對客戶進行參數化;對請求排隊或記錄日志,以及支持可撤銷的操作,將”發出請求的對象”和”接收與執行這些請求的對象”分隔開來。
命令模式(Command)的適用性
1.抽象出待執行的動作以參數化某對象。
2.在不同的時刻指定、排列和執行請求。
3.支持取消操作。
4.支持修改日志,這樣當系統崩潰時,這樣修改可以被重做一遍。
5.用構建在原語操作上的高層操作構造一個系統。
命令模式(Command)的應用效果:
1)command模式將調用操作的對象和實現該操作的對象解耦
2)可以將多個命令裝配成一個復合命令,復合命令是Composite模式的一個實例
3)增加新的command很容易,無需改變已有的類
命令模式(Command)的參與者
1.Command
聲明執行操作的接口。
2.ConcreteCommand
將一個接收者對象綁定於一個動作。
調用接收者相應的操作,以實現Execute。
3.Client
創建一個具體命令對象並設定它的接收者。
4.Invoker
要求該命令執行這個請求。
5.Receiver
知道如何實現與執行一個請求相關的操作。任何類都可能作為一個接收者。
命令模式(Command)的UML類圖
具體的代碼實現:
第一步:定義Command,聲明執行操作的接口
//命令接口 public interface Command { //執行操作 public void excute(); //撤銷操作 public void unDo(); }
第二步:定義ConcreteCommand,將一個接收者對象綁定於一個動作。
public class ConcreteCommand implements Command { // 持有一個接受者Receiver的引用,綁定一個特定的操作 Receiver receiver; public ConcreteCommand(Receiver receiver) { this.receiver = receiver; } @Override public void excute() { // 接受者綁定執行動作 receiver.action(); } @Override public void unDo() { // 接受者綁定的撤銷動作 receiver.unAction(); } }
第三步:定義Receiver,知道如何實現與執行一個請求相關的操作
public class Receiver { public void action() { System.out.println("執行一個命令"); } public void unAction() { System.out.println("撤銷一個命令"); } }
第四步:定義Invoker,要求該命令執行這個請求。
public class Invoker { // 調用者持有一個命令對象 Command command; public Command getCommand() { return command; } public void setCommand(Command command) { this.command = command; } // 執行命令 public void excuteCommmand() { command.excute(); } // 撤銷命令 public void undoCommand() { command.unDo(); } }
第五步:定義Clien,我們來測試一下我們的命令模式
public class Client { /** * @param args */ public static void main(String[] args) { // 創建命令的接受者 Receiver receiver = new Receiver(); // 創建命令對象,並設定它的接受者 Command command = new ConcreteCommand(receiver); // 創建命令執行者,並將相應的命令作為參數傳遞給Invoker Invoker invoker = new Invoker(); invoker.setCommand(command); // Client端測試一下 invoker.excuteCommmand(); invoker.undoCommand(); } }
運行結果:
執行一個命令 撤銷一個命令
總結:
1、在被解耦的兩者之間是通過命令對象進行溝通的,命令對象封裝了接收者和一個或一組動作;
2、調用者通過調用命令對象的execute()發出請求,這會使得接收者的動作被調用;
3、調用者可以接受命令當作參數,甚至在運行時動態的進行;
4、命令可以支持撤銷,做法是實現一個undo()方法來回到execute()被執行前的狀態;
5、命令模式將發出請求的對象和執行請求的對象進行解耦;