備忘錄模式(讓對象返回之前的狀態)

源碼地址 https://github.com/DingMouRen/DesignPattern
備忘錄模式.png
  • Originator 原發器,負責創建一個備忘錄,可以記錄、恢復自身的內部狀態,同時還可以根據需要決定Memento存儲自身的哪些狀態。
  • Memento 備忘錄角色,用于存儲Originator的內部狀態,并且可以防止Originator以外的對象訪問Memento.
  • Caretaker 管理者,負責存儲備忘錄,不能對備忘錄的內容進行操作和訪問,只能將備忘錄傳遞給其他對象。
定義

備忘錄模式在不破壞封閉的前提下,捕獲一個對象的內部狀態,并在該對象之外保存這個狀態,這樣就可以將該對象恢復到原來保存的狀態。

使用場景
  • 需要保存一個對象在某一個時刻的狀態或部分狀態
  • 如果用一個接口來讓其他對象得到這些狀態,將會暴露對象的實現細節并破壞對象的封裝性。一個對象不希望外界直接訪問其內部狀態,通過中間對象可以間接訪問其內部狀態。
舉個例子

我們玩游戲的時候都有游戲存檔的事情,基本流程:游戲開始--獲取存檔信息--開始游戲--退出游戲時進行存檔,循環往復。

//備忘錄類
public class Memoto {
    private int checkPoint;//關數
    private int lifeValue;//血量
    private String weapon;//武器

    public int getCheckPoint() {
        return checkPoint;
    }

    public void setCheckPoint(int checkPoint) {
        this.checkPoint = checkPoint;
    }

    public int getLifeValue() {
        return lifeValue;
    }

    public void setLifeValue(int lifeValue) {
        this.lifeValue = lifeValue;
    }

    public String getWeapon() {
        return weapon;
    }

    public void setWeapon(String weapon) {
        this.weapon = weapon;
    }
    @Override
    public String toString() {
        return "備忘錄中存儲的游戲關數:"+checkPoint+"  血量:"+lifeValue+" 武器:"+weapon;
    }
}

//相當于Originator,
public class Game {
    private int checkPoint = 1;//游戲第一關
    private int lifeValue = 100;//剛開始血量滿滿
    private String weapon = "匕首";//武器

    //開始游戲
    public void play(){
        System.out.println("開始游戲:"+String.format("第%d關",checkPoint)+"  fighting!! ︻$▅▆▇◤");
        lifeValue -= 10;
        System.out.println("闖關成功");
        checkPoint++;
        System.out.println("到達"+String.format("第%d關",checkPoint));
    }

    //退出游戲
    public void quit(){
        System.out.println(". . . . . .");
        System.out.println(this.toString()+"\n退出游戲");
    }

    //創建備忘錄
    public Memoto createMemoto(){
        Memoto memoto = new Memoto();
        memoto.setCheckPoint(this.checkPoint);
        memoto.setLifeValue(lifeValue);
        memoto.setWeapon(weapon);
        return memoto;
    }

    //恢復游戲
    public void restore(Memoto memoto){
        this.checkPoint = memoto.getCheckPoint();
        this.lifeValue = memoto.getLifeValue();
        this.weapon = memoto.getWeapon();
        System.out.println("恢復后的游戲狀態:"+this.toString());
    }

    @Override
    public String toString() {
        return "當前游戲關數:"+checkPoint+"  血量:"+lifeValue+" 武器:"+weapon;
    }
}
//管理者  管理備忘錄
public class Caretaker {
    private Memoto memoto;//備忘錄
    //存檔
    public void saveMemoto(Memoto memoto){
        this.memoto = memoto;
    }
    //獲取存檔

    public Memoto getMemoto() {
        return memoto;
    }
}
使用
    public static void main(String[] args) {
        //構建游戲對象
        Game game = new Game();
        //構建管理者
        Caretaker caretaker =  new Caretaker();
        //開始游戲
        game.play();
        //游戲存檔
        caretaker.saveMemoto(game.createMemoto());
        //退出游戲
        game.quit();
        //進入游戲時,恢復上一次游戲的狀態
        Game newGame = new Game();
        System.out.println("登錄游戲");
        newGame.restore(caretaker.getMemoto());
    }
總結

備忘錄模式是在不破壞封裝的條件下,通過備忘錄對象Memoto存儲另外一個對象內部狀態的快照,在將來合適的時候把這個對象還原到存儲的狀態。

備忘錄模式優點自然是為用戶提供了一個可以恢復狀態的機制,可以讓用戶方便的回到某個歷史的狀態,缺點就是在類成員變量變多的情況下,勢必消耗資源,每一次保存都會消耗一定的內存。

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

推薦閱讀更多精彩內容