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

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

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

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

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

//備忘錄類
public class Memoto {
    private int checkPoint;//關(guān)數(shù)
    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 "備忘錄中存儲的游戲關(guān)數(shù):"+checkPoint+"  血量:"+lifeValue+" 武器:"+weapon;
    }
}

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

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

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

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

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

    @Override
    public String toString() {
        return "當前游戲關(guān)數(shù):"+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) {
        //構(gòu)建游戲?qū)ο?        Game game = new Game();
        //構(gòu)建管理者
        Caretaker caretaker =  new Caretaker();
        //開始游戲
        game.play();
        //游戲存檔
        caretaker.saveMemoto(game.createMemoto());
        //退出游戲
        game.quit();
        //進入游戲時,恢復(fù)上一次游戲的狀態(tài)
        Game newGame = new Game();
        System.out.println("登錄游戲");
        newGame.restore(caretaker.getMemoto());
    }
總結(jié)

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

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

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

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

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