Android中的設計模式之命令模式

參考

  • 《設計模式:可複用面向對象軟件的基礎 》5.2 Command 命令 對象行爲型模式
  • 《Android源碼設計模式解析與實戰》第11章 讓程序暢通執行–命令模式

意圖

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

適用場景

  • 需要抽象出待執行地動作,然後以參數地形式提供出來,類似於過程設計中的回調機制,命令模式正是回調機制的一個面向對象的替代品
  • 在不同的時刻指定、排列和執行請求。一個命令對象可以有與初始請求無關的生存期。
  • 需要支持取消操作。
  • 支持修改日誌功能,這樣當系統崩潰時,這些修改可以被重做一遍。
  • 需要支持事物操作。

結構

命令模式通用結構

  • Reicever 接收者角色,負責具體執行一個請求,任何一個類都可以成爲一個接收者,而在接收者類中封裝具體操作邏輯的方法我們稱爲行動方法(action)
  • Command 命令角色 定義所有具體命令類的抽象接口
  • ConcreteCommand 具體命令角色,實現了Command接口,在excute方法中調用接收者角色的相關方法,在接收者和命令執行的具體行爲之間加以弱耦合。execute方法成爲執行方法(excute)
  • Invoker 請求者角色,負責調用命令對象執行具體的請求,相關的方法我們成爲行動方法(action)
  • Client 客戶端角色

執行流程

執行流程

代碼就略了

優點

更弱的耦合性,更靈活的控制性以及更好的擴展性

缺點

類膨脹,大量衍生類的創建。

例子1 操縱俄羅斯方塊變換

描述

大家小時候都玩過俄羅斯方塊,遊戲中有4個按鈕,分別是兩個左右移動的按鈕,一個快速落下的按鈕,一個變化方塊形狀的按鈕。所以四個按鈕就相當於請求者,執行具體按鈕命令的邏輯方法塊可以看作命令角色。

結構

結構

代碼實現

/**
 *  命令的接收者,負責具體執行請求
 * @author newtrekWang
 * @email  [email protected]
 * @time   2018/8/20  23:35
 */
public class TetrisMachine {

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

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

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

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

/**
 *  命令抽象
 * @author newtrekWang
 * @email  [email protected]
 * @time   2018/8/20  23:37
 */
public interface Command {
    /**
     * 執行命令
     */
    void execute();
}


/**
 *  向左命令
 * @author newtrekWang
 * @email  [email protected]
 * @time   2018/8/20  23:39
 */
public class LeftCommand implements Command {
    private TetrisMachine tetrisMachine;

    public LeftCommand(TetrisMachine tetrisMachine) {
        this.tetrisMachine = tetrisMachine;
    }

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

/**
 *  向右命令
 * @author newtrekWang
 * @email  [email protected]
 * @time   2018/8/20  23:39
 */
public class RightCommand implements Command {
    private TetrisMachine tetrisMachine;

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

    @Override
    public void execute() {
        tetrisMachine.toRigth();
    }
}

/**
 *  快速向下命令
 * @author newtrekWang
 * @email  [email protected]
 * @time   2018/8/20  23:39
 */
public class FallCommand implements Command {
    private TetrisMachine tetrisMachine;

    public FallCommand(TetrisMachine tetrisMachine) {
        this.tetrisMachine = tetrisMachine;
    }

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

/**
 *  變換形狀命令
 * @author newtrekWang
 * @email  [email protected]
 * @time   2018/8/20  23:39
 */
public class TransformCommand implements Command {
    private TetrisMachine tetrisMachine;

    public TransformCommand(TetrisMachine tetrisMachine) {
        this.tetrisMachine = tetrisMachine;
    }

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

 public static void main(String[] args){
        TetrisMachine tetrisMachine = new TetrisMachine();

        LeftCommand leftCommand = new LeftCommand(tetrisMachine);
        RightCommand rightCommand = new RightCommand(tetrisMachine);
        FallCommand fallCommand = new FallCommand(tetrisMachine);
        TransformCommand transformCommand = new TransformCommand(tetrisMachine);

        leftCommand.execute();
        leftCommand.execute();
        fallCommand.execute();
        transformCommand.execute();
        rightCommand.execute();

    }

執行結果:

向左
向左
快速向下
變換形狀
向右

例子2 Android事件機制中底層邏輯對事件的轉發處理

Android的每一種事件在屏幕上產生後都會經由底層邏輯將其轉換爲一個NotifyArgs對象,NotifyAgs本身並無實現,其實它就相當於一個Command抽象。

例子3 運用命令模式實現Android繪圖板

後更

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