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

介紹

將一個請求封裝成一個對象,從而讓用戶使用不同的請求把客戶端參數(shù)化,對請求排隊或者記錄請求日志,以及支持可撤銷的操作,

應(yīng)用場景

  1. 需要抽象出待執(zhí)行的動作,然后以參數(shù)的形式體統(tǒng)出來——類似過程設(shè)計中的回調(diào)機制
  2. 在不同的時刻指定、排序和執(zhí)行的請求,一個命令對象可以有與初始請求無關(guān)的生存期
  3. 需要支持取消操作
  4. 支持修改日志
  5. 需要支持事務(wù)

UML

UML.png

具體代碼實現(xiàn)

以俄羅斯方塊中的按鍵為例

  • 接收者角色
public class TetrisMachine {

    public void toLeft() {
        System.out.println("向左");
    }

    public void toRight() {
        System.out.println("向右");
    }

    public void fastToBottom() {
        System.out.println("快速下降");
    }

    public void transform() {
        System.out.println("改變形狀");
    }


}
  • 抽象命令接口
public interface Command {

    void execute();
}
  • 具體命令類
public class FallCommand implements Command {

    private TetrisMachine machine;
    public FallCommand(TetrisMachine machine) {
        this.machine = machine;
    }

    @Override
    public void execute() {
        machine.fastToBottom();
    }
}

public class LeftCommand implements Command {

    private TetrisMachine machine;
    public LeftCommand(TetrisMachine machine) {
        this.machine = machine;
    }

    @Override
    public void execute() {
        machine.toLeft();
    }
}

public class RightCommand implements Command {

    private TetrisMachine machine;

    public RightCommand(TetrisMachine machine) {
        this.machine = machine;
    }

    @Override
    public void execute() {
        machine.toRight();
    }
}

public class TransformCommand implements Command {

    private TetrisMachine machine;
    public TransformCommand(TetrisMachine machine) {
        this.machine = machine;
    }

    @Override
    public void execute() {
        machine.transform();
    }
}

  • 請求角色
public class Buttons {

    private LeftCommand leftCommand;
    private RightCommand rightCommand;
    private FallCommand fallCommand;
    private TransformCommand transformCommand;

    public void setLeftCommand(LeftCommand leftCommand) {
        this.leftCommand = leftCommand;
    }

    public void setRightCommand(RightCommand rightCommand) {
        this.rightCommand = rightCommand;
    }

    public void setFallCommand(FallCommand fallCommand) {
        this.fallCommand = fallCommand;
    }

    public void setTransformCommandl(TransformCommand transformCommand) {
        this.transformCommand = transformCommand;
    }

    public void toLeft() {
        leftCommand.execute();
    }

    public void toRight() {
        rightCommand.execute();
    }

    public void fallTo() {
        fallCommand.execute();
    }

    public void transform() {
        transformCommand.execute();
    }
}
  • 客戶端
public static void main(String[] args) {
        Buttons buttons = new Buttons();
        TetrisMachine machine = new TetrisMachine();
        LeftCommand leftCommand = new LeftCommand(machine);
        RightCommand rightCommand = new RightCommand(machine);
        FallCommand fallCommand = new FallCommand(machine);
        TransformCommand transformCommand = new TransformCommand(machine);

        buttons.setFallCommand(fallCommand);
        buttons.setRightCommand(rightCommand);
        buttons.setTransformCommandl(transformCommand);
        buttons.setLeftCommand(leftCommand);

        buttons.toRight();
        buttons.toLeft();
    }
  • 輸出結(jié)果
輸出結(jié)果.png

其實到這里會有很多讀者會感到疑惑,明明可以只用一個類就解決的問題,硬是被解耦成多個部分,增加代碼的復(fù)雜度,為什么呢?
其實是為了設(shè)計模式的一個重要原則:對修改關(guān)閉,對擴展開放,這里大家慢慢體會。

總結(jié)

在命令模式中充分體現(xiàn)了幾乎所有模式的通病,就是類的膨脹,大量衍生類的創(chuàng)建,這是一個不可避免的問題,但是給我們帶來的好處也是非常多,更弱的耦合性,更靈敏的控制性,以及更好的擴展性,不過在實際開發(fā)中是否使用命令模式是要好好斟酌的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容