設(shè)計模式-命令模式

介紹

說到命令模式,我們可以聯(lián)想到上級下達(dá)命令,下級接收命令去執(zhí)行,遙控器發(fā)送命令,相應(yīng)的機(jī)器做出反應(yīng)。就比如電燈泡的開關(guān),排氣扇的開關(guān)等等。這些開關(guān)就是發(fā)送命令的對象,而電燈泡和排氣扇就是接受命令的對象,如下圖。


這里寫圖片描述

命令模式(Command Pattern)是一種數(shù)據(jù)驅(qū)動的設(shè)計模式,它屬于行為型模式。請求以命令的形式包裹在對象中,并傳給調(diào)用對象。調(diào)用對象尋找可以處理該命令的合適的對象,并把該命令傳給相應(yīng)的對象,該對象執(zhí)行命令。命令模式可以對發(fā)送者和接收者完全解耦,發(fā)送者與接收者之間沒有直接引用關(guān)系,發(fā)送請求的對象只需要知道如何發(fā)送請求,而不必知道如何完成請求。這就是命令模式的模式動機(jī)。

角色

● Command(抽象命令類):抽象命令類一般是一個抽象類或接口,在其中聲明了用于執(zhí)行請求的execute()等方法,通過這些方法可以調(diào)用請求接收者的相關(guān)操作。
● ConcreteCommand(具體命令類):具體命令類是抽象命令類的子類,實(shí)現(xiàn)了在抽象命令類中聲明的方法,它對應(yīng)具體的接收者對象,將接收者對象的動作綁定其中。在實(shí)現(xiàn)execute()方法時,將調(diào)用接收者對象的相關(guān)操作(Action)。
● Invoker(調(diào)用者):調(diào)用者即請求發(fā)送者,它通過命令對象來執(zhí)行請求。一個調(diào)用者并不需要在設(shè)計時確定其接收者,因此它只與抽象命令類之間存在關(guān)聯(lián)關(guān)系。在程序運(yùn)行時可以將一個具體命令對象注入其中,再調(diào)用具體命令對象的execute()方法,從而實(shí)現(xiàn)間接調(diào)用請求接收者的相關(guān)操作。
● Receiver(接收者):接收者執(zhí)行與請求相關(guān)的操作,它具體實(shí)現(xiàn)對請求的業(yè)務(wù)處理。
結(jié)構(gòu)圖


這里寫圖片描述

時序圖

這里寫圖片描述

案例

這里就用電燈的開關(guān)作為案例
接收者接口

public interface Receiver {
    void action();
}

電燈接收者類
有個flag表示電燈狀態(tài)是否是開啟還是關(guān)閉

public class LightReceiver implements Receiver{
    
    private boolean flag = false;

    @Override
    public void action() {
        if (flag) {
            System.out.println("燈現(xiàn)在是開著的");
        } else {
            System.out.println("燈已經(jīng)關(guān)了");
        }
    }
    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}

命令接口

public interface Command {
    void execute();
}

電燈命令類

public class LightCommand implements Command{
    private LightReceiver lightReceiver;
    
    public LightCommand(LightReceiver lightReceiver) {
        super();
        this.lightReceiver = lightReceiver;
    }

    @Override
    public void execute() {
        boolean flag = lightReceiver.isFlag() ? false : true;
        lightReceiver.setFlag(flag);
        lightReceiver.action();
    }

}

開關(guān)類

public class SwitchInvoker {
    private Command command;

    public SwitchInvoker(Command command) {
        this.command = command;
    }
    
    public void executeCommand(){
        command.execute();
    }
}

測試類

public class Client {

    public static void main(String[] args) {
        Command command = new LightCommand(new LightReceiver());
        SwitchInvoker invoker = new SwitchInvoker(command);
        for (int i = 0; i < 6; i++) {
            invoker.executeCommand();
        }
    }
}

測試結(jié)果

這里寫圖片描述

總結(jié)
--
使用命令模式可以降低了系統(tǒng)耦合度,也比較容易擴(kuò)展,但是也可能會導(dǎo)致某些系統(tǒng)有過多的具體命令類。
在碰到需要對行為進(jìn)行"記錄、撤銷/重做、事務(wù)"等處理時,或者系統(tǒng)需要將請求調(diào)用者和請求接收者解耦,使得調(diào)用者和接收者不直接交互,又或者系統(tǒng)需要在不同的時間指定請求、請求排隊和執(zhí)行請求時就可以使用命令模式。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容