[設計模式]命令模式

一、命令模式介紹

命令模式:將一個請求封裝爲一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤銷的操作。

說白了,就是將一系列的請求命令封裝起來,不直接調用真正執行者的方法,這樣比較好擴展。

命令模式UML圖:

Command(抽象命令類):抽象出命令對象,可以根據不同的命令類型,寫出不同的實現類。

ConcreteCommand(具體命令類):實現了抽象命令對象的具體實現。

Invoker(調用者/請求者):請求的發送者,它通過命令對象來執行請求。一個調用者並不需要在設計時確定其接收者,因此它只與抽象命令來之間存在關聯。在程序運行時,將調用命令對象的execute() ,間接調用接收者的相關操作。

Receiver(接收者):接收者執行與請求相關的操作,真正執行命令的對象。具體實現對請求的業務處理。任何類都可能作爲一個接收者。

Client(客戶端):在客戶類中需要創建調用者對象,具體命令類對象,在創建具體命令對象時指定對應的接收者。發送者和接收者之間沒有之間關係,都通過命令對象來調用。

二、命令模式代碼實現

首先定義一個命令的接收者,也就是到最後真正執行命令的那個對象。

//接收者:真正執行命令的對象
public class Receiver {
    public void action(){
        System.out.println("命令執行了.......");
    }
}

然後定義抽象命令和抽象命令的具體實現,具體命令類中需要持有真正執行命令的那個對象。

//抽象命令類:抽象的命令,可以根據不同類型的命令寫出不同的實現
public interface Command {
    //調用命令,還可以定義其他方法,比如撤銷undo
    void execute();
}
//具體命令類
class ConcreteCommand implements Command{
    private Receiver receiver;//持有真正執行命令對象的引用,可以使用容器持有多個receiver
    public ConcreteCommand(Receiver receiver) {
        this.receiver = receiver;
    }
    @Override
    public void execute() {
        //調用接收者執行命令的方法,調用前後可以做相關處理
        receiver.action();
    }
}

接下來就可以定義命令的發起者了,發起者需要持有一個命令對象,以便來發起命令。

//請求者/調用者:發起執行命令請求的對象
public class Invoker {
    private Command command;//持有命令對象的引用,可以使用容器持有多個command
    public Invoker(Command command) {
        this.command = command;
    }
    public void call(){
        //請求者調用命令對象執行命令的那個execute方法,調用前後可以做相關處理
        command.execute();
    }
}

客戶端測試:客戶端

public static void main(String[] args) {
    //通過請求者(invoker)調用命令對象(command),命令對象中調用了命令具體執行者(Receiver)
    Command command = new ConcreteCommand(new Receiver());
    Invoker invoker = new Invoker(command);
    invoker.call();
}

結果打印:命令執行了.......

代碼的UML圖如下:

三、應用場景

Struts2中action中的調用過程中存在命令模式。

數據庫中的事務機制的底層實現。

命令的撤銷和恢復:增加相應的撤銷和恢復命令的方法(比如數據庫中的事務回滾)。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章