設計模式之命令模式

—阿輝發表於2021-08-19

命令模式是一種行為模式。

命令模式的定義

命令模式是一個高內聚的模式,將一個請求封裝成一個物件,從而讓你使用不同的請求把客戶端引數化,對請求排隊或者記錄日誌,可以提供命令的撤銷和恢復功能。命令模式的核心在於引入了命令類,通過命令類來降低傳送者和接收者的耦合度,請求傳送者只需指定一個命令物件,再通過命令物件來呼叫請求接收者的處理方法。

Command
命令模式

命令模式可以將請求傳送者和接收者完全解耦,傳送者與接收者之間沒有直接引用關係,傳送請求的物件只需要知道如何傳送請求,而不必知道如何完成請求。

命令模式的結構

命令模式包含如下角色:

  • Receiver接收者角色
    命令接收者模式,命令傳遞到這裡執行對應的操作。

  • Command命令角色
    需要執行的命令都在這裡宣告

  • Invoker呼叫者角色
    接收到命令,並執行命令,也就是命令的發動者和呼叫者

命令模式的實現

抽象Command類。

public abstract class Command {  
    public abstract void execute();  
}
複製程式碼

呼叫者Invoker類。

public class Invoker {  
    private Command command;  
      
    //構造注入  
    public Invoker(Command command) {  
        this.command = command;  
    }  
      
    //設值注入  
    public void setCommand(Command command) {  
        this.command = command;  
    }  
      
    //業務方法,用於呼叫命令類的execute()方法  
    public void call() {  
        command.execute();  
    }  
}  
複製程式碼

具體Command類,設定對應的接收者。

public  class ConcreteCommand extends Command {  
    private Receiver receiver; //維持一個對請求接收者物件的引用  
  
    public ConcreteCommand(Receiver receiver) {
        super();
        this.receiver = receiver;
    }

    public void execute() {  
        receiver.action(); //呼叫請求接收者的業務處理方法action()  
    }  
}  
複製程式碼

抽象接收者。

public  abstract class Receiver {  
    public abstract void action();
}  
複製程式碼

第一個接收者。

public class ConcreteReceiver extends Receiver{

    @Override
    public void action() {
        System.out.println("ConcreteReceiver receives the command!");
    }

}
複製程式碼

第二個接收者。

public class ConcreteReceiver2 extends Receiver{

    @Override
    public void action() {
        System.out.println("ConcreteReceiver2 receives the command!");
    }

}
複製程式碼

測試類,建立了連個接收者,分別傳送指令。

public class Client {

    public static void main(String[] args) {
        Receiver receiver1 = new ConcreteReceiver();
        Command command1 = new ConcreteCommand(receiver1);

        Invoker invoker = new Invoker();
        invoker.setCommand(command1);
        invoker.call();

        Receiver receiver2 = new ConcreteReceiver2();
        Command command2 = new ConcreteCommand(receiver2);

        invoker.setCommand(command2);
        invoker.call();
    }
}
複製程式碼

總結

命令模式的本質是對請求進行封裝,一個請求對應於一個命令,將發出命令的責任和執行命令的責任分割開。每一個命令都是一個操作:請求的一方發出請求要求執行一個操作;接收的一方收到請求,並執行相應的操作。命令模式允許請求的一方和接收的一方獨立開來,使得請求的一方不必知道接收請求的一方的介面,更不必知道請求如何被接收、操作是否被執行、何時被執行,以及是怎麼被執行的。命令模式的關鍵在於引入了抽象命令類,請求傳送者針對抽象命令類程式設計,只有實現了抽象命令類的具體命令才與請求接收者相關聯。

命令模式的優點是:

  • 類間解藕
    呼叫者角色與接受者角色之間沒有任何依賴關係,呼叫者實現功能時只需要呼叫Command抽象類的execute方法就可以,不需要知道到底是哪個接收者執行。

  • 可擴充套件性
    Command子類可以非常容易的擴充套件,而呼叫者Invoker和高層次的模組Client不產生嚴重的程式碼藕合

其缺點是造成了類膨脹,如果有多個子命令對應多個Command子類,比較繁瑣。

訂閱最新文章,歡迎關注我的公眾號

微信公眾號

參考

  1. java設計模式之命令模式
  2. 設計模式之命令模式---Command Pattern

相關文章