一、定義
命令模式是一個高內聚的模式,其定義為:Encapsulate a request as an object,there by letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(將一個請求封裝成一個對象,從而讓你使用不同的請求把客戶端參數化,對請 求排隊或者記錄請求日志,可以提供命令的撤銷和恢復功能。)
通用類圖:
在該類圖中,我們看到三個角色:
- Receiver接受者角色:該角色就是干活的角色,命令傳遞到這里是應該被執行的
- Command命令角色:需要執行的所有命令都在這里聲明
- Invoker調用者角色:接收到命令,並執行命令
//通用Receiver類
public abstract class Receiver {
public abstract void doSomething();
}
//具體Receiver類
public class ConcreteReciver1 extends Receiver{
//每個接收者都必須處理一定的業務邏輯
public void doSomething(){ }
}
public class ConcreteReciver2 extends Receiver{
//每個接收者都必須處理一定的業務邏輯
public void doSomething(){ }
}
//抽象Command類
public abstract class Command {
public abstract void execute();
}
//具體的Command類
public class ConcreteCommand1 extends Command {
//對哪個Receiver類進行命令處理
private Receiver receiver;
//構造函數傳遞接收者
public ConcreteCommand1(Receiver _receiver){
this.receiver = _receiver;
}
//必須實現一個命令
public void execute() {
//業務處理
this.receiver.doSomething();
}
}
public class ConcreteCommand2 extends Command {
//哪個Receiver類進行命令處理
private Receiver receiver;
//構造函數傳遞接收者
public ConcreteCommand2(Receiver _receiver){
this.receiver = _receiver;
}
//必須實現一個命令
public void execute() {
//業務處理
this.receiver.doSomething();
}
}
//調用者Invoker類
public class Invoker {
private Command 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 receiver = new ConcreteReceiver1();
Command command = new ConcreteCommand1(receiver);
invoker.setCommand(command);
invoker.action();
}
}
二、應用
2.1 優點
- 類間解耦:調用者角色與接收者角色之間沒有任何依賴關系,調用者實現功能時只需調用Command 抽象類的execute方法就可以,不需要了解到底是哪個接收者執行。
- 可擴展性:Command的子類可以非常容易地擴展,而調用者Invoker和高層次的模塊Client不產生嚴 重的代碼耦合。
- 命令模式結合其他模式會更優秀:命令模式可以結合責任鏈模式,實現命令族解析任務;結合模板方法模式,則可以減少 Command子類的膨脹問題。
2.2 缺點
命令模式也是有缺點的,請看Command的子類:如果有N個命令,問題就出來 了,Command的子類就可不是幾個,而是N個,這個類膨脹得非常大,這個就需要讀者在項 目中慎重考慮使用。