類圖
定義
將一個請求封裝成一個對象,從而讓你使用不同的請求把客戶端參數化,對請求排隊或者記錄請求日誌,可以提供命令的撤銷和恢復功能
優點
- 類間解耦 調用者Invoker與接受者receiver之間沒任何依賴關係,調用者不需要瞭解到底哪個接收者執行
- 可擴展性 command子類可非常容易的擴展
- 命令模式結合其他模式會更優秀 如結合責任鏈模式,模板方法模式缺點
- N個命令,N個Command,容易造成類膨脹
使用場景
GUI中,按鈕點擊;觸發-反饋機制
擴展
實際設計中,可以選擇減少Client類和Receiver類的依賴關係
抽象命令類
public abstract class Command {
/**
* 每個命令類都必須有一個執行命令的方法
*/
public abstract void execute();
}
具體命令類
public class ConcreteCommand extends Command {
// 對哪個receiver進行命令處理
private Receiver receiver;
/**
* 命令構造函數,關聯命令接收者
*
* @param _receiver 命令接收者
*/
public ConcreteCommand(Receiver _receiver) {
receiver = _receiver;
}
/**
* 命令執行函數
*/
@Override
public void execute() {
// 執行命令動作
System.out.println("命令" + hashCode() + ":開始執行");
// 接收者處理命令
receiver.doSomething();
}
}
抽象接收者
public abstract class Receiver {
/**
* 定義每個接受者都必須完成的業務
*/
public abstract void doSomething();
}
具體接收者
public class ConcreteReceiver extends Receiver {
@Override
public void doSomething() {
System.out.println("接收者" + hashCode() + ":執行命令");
}
}
調用者類
public class Invoker {
private Command command;
/**
* 設置命令
*
* @param _command 命令
*/
public void setCommand(Command _command) {
this.command = _command;
}
/**
* 執行命令動作
*/
public void action() {
this.command.execute();
}
}
場景類
public class Client {
public static void main(String[] args) {
// 新建調用者類
Invoker invoker = new Invoker();
// 新建接收者類
Receiver receiver1 = new ConcreteReceiver();
Receiver receiver2 = new ConcreteReceiver();
// 新建命令類
Command command1 = new ConcreteCommand(receiver1);
Command command2 = new ConcreteCommand(receiver1);
Command command3 = new ConcreteCommand(receiver2);
// 調用者設置命令
invoker.setCommand(command1);
// 調用者執行命令
invoker.action();
invoker.setCommand(command2);
invoker.action();
invoker.setCommand(command3);
invoker.action();
}
}
運行結果
命令1808253012:開始執行
接收者589431969:執行命令
命令1252169911:開始執行
接收者589431969:執行命令
命令2101973421:開始執行
接收者685325104:執行命令