設計模式(九)備忘錄模式


更多設計模式文章請閱讀:

設計模式專欄

1.定義:

備忘錄模式屬於行爲型模式,它通過在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。

2.簡單描述:

備忘錄模式用戶保存對象的狀態,並且以後恰當時間可以再次恢復到此狀態。即可以保存和獲取該對象的狀態。

3.UML建模圖

在這裏插入圖片描述

UML角色解讀:

  • Memoto:備忘錄角色,用於保存Originator中的狀態
  • Originator:負責創建備忘錄,可以記錄和恢復自身內部維護的狀態對象
  • Caretaker:負責存儲備忘錄,不對備忘錄的內容操作和訪問,只能將對象傳遞給其他對象。

4.簡單示例:

備忘錄模式以遊戲中最爲常見,比如玩遊戲玩到什麼進度,下次進入遊戲的時候回直接從上次退出的進度中繼續玩。就以該示例爲示範,在代碼中是如何實現。

  • Memoto對象
/**
 * 備忘錄類
 */
public class Memoto {

    /**
     * 用戶ID
     */
    public String userId;
    /**
     * 遊戲進度
     */
    public int progress;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public int getProgress() {
        return progress;
    }

    public void setProgress(int progress) {
        this.progress = progress;
    }
}
  • Caretaker對象
/**
 * 負責Memoto類的存儲
 */
public class Caretaker {
    private Memoto mMemoto;

    /**
     * 保存狀態
     * @param memoto 備忘錄對象
     */
    public void saveMemoto(Memoto memoto){
        this.mMemoto=memoto;
    }

    /**
     * 獲取狀態對象
     * @return
     */
    public Memoto getMemoto(){
        return mMemoto;
    }

}
  • Originator對象
/**
 * 需要備忘的角色
 */
public class LolGame {

    private String userId;
    private int progress = 0;
    private String monemy;
    private Memoto mMemoto;

    public void play() {

        userId = getUserId();
        ++progress;
        System.out.println("開始玩遊戲了...");
        System.out.println("--- userId: " + userId + " --- progress: " +progress+ " ---");

    }

    /**
     * 退出遊戲
     */
    public void quit(){
        System.out.println("退出遊戲了...");
    }


    /**
     * 創建備忘錄對象
     *
     * @return
     */
    public Memoto createMemoto() {
        mMemoto = new Memoto();
        mMemoto.userId = userId;
        mMemoto.progress = progress;
        return mMemoto;
    }

    /**
     * 恢復備忘錄
     */
    public void restoreMemoto(Memoto memoto) {
        this.userId = memoto.userId;
        this.progress = memoto.progress;
        System.out.println("----恢復備忘錄----");
    }


    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public int getProgress() {
        return progress;
    }

    public void setProgress(int progress) {
        this.progress = progress;
    }

}
  • 遊戲類
/**
 * 玩家玩遊戲
 */
public class Client {
    public static void main(String[] args) {
        LolGame player = new LolGame();
        player.setUserId("onex");
        player.play();

        Caretaker caretaker =new Caretaker();
        caretaker.saveMemoto(player.createMemoto());

        player.quit();

        player = new LolGame();

        player.restoreMemoto(caretaker.getMemoto());
        player.play();

    }
}
  • 運行結果:
開始玩遊戲了...
--- userId: onex --- progress: 1 ---
退出遊戲了...
----恢復備忘錄----
開始玩遊戲了...
--- userId: onex --- progress: 2 ---

Process finished with exit code 0

5.Android中的備忘錄設計模式:

在Android開發中,狀態模式應用是Activity中的狀態保存,即onSaveInstanceState和OnRestoreInstanceState實現ViewGroup和View的狀態的保存和恢復

保存Activity的對象即View的狀態

 protected void onSaveInstanceState(Bundle outState) {
        outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());

        outState.putInt(LAST_AUTOFILL_ID, mLastAutofillId);
        Parcelable p = mFragments.saveAllState();
        if (p != null) {
            outState.putParcelable(FRAGMENTS_TAG, p);
        }
        if (mAutoFillResetNeeded) {
            outState.putBoolean(AUTOFILL_RESET_NEEDED, true);
            getAutofillManager().onSaveInstanceState(outState);
        }
        getApplication().dispatchActivitySaveInstanceState(this, outState);
    }

恢復View(ViewGroup)的狀態

   protected void onRestoreInstanceState(Bundle savedInstanceState) {
        if (mWindow != null) {
            Bundle windowState = savedInstanceState.getBundle(WINDOW_HIERARCHY_TAG);
            if (windowState != null) {
                mWindow.restoreHierarchyState(windowState);
            }
        }
    }

即Bundle爲Memoto對象,Activity爲Caretaker對象,View(ViewGroup)爲Originator

6.備忘錄優缺點:

優點
給對象提供狀態可恢復的機制,使得對象方便恢復到歷史的狀態
實現了信息的封裝,使得用戶不用關心狀態的保存細節

缺點
消耗資源,如果類的成員變量很多及保需要保存的狀態太多,會消耗一定的內存

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