設(shè)計模式_19_備忘錄模式

基本介紹.
  1. 備忘錄模式(Memento Pattern) 在不破壞封裝性的前提下,捕獲-一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài)。這樣以后就可將該對象恢復(fù)到原先保存的狀態(tài)
  2. 可以這里理解備忘錄模式:現(xiàn)實生活中的備忘錄是用來記錄某些要去做的事情,或者是記錄已經(jīng)達(dá)成的共同意見的事情,以防忘記了。而在軟件層面,備忘錄模式有著相同的含義,備忘錄對象主要用來記錄一個對象的某種狀態(tài),或者某些數(shù)據(jù),當(dāng)要做回退時,可以從備忘錄對象里獲取原來的數(shù)據(jù)進(jìn)行恢復(fù)操作
  3. 備忘錄模式屬于行為型模式


    image.png

例子:
需求:游戲角色狀態(tài)恢復(fù)問題
游戲角色有攻擊力和防御力。在大戰(zhàn)Boss前保存自身的狀態(tài)(攻擊力和防御力),當(dāng)大戰(zhàn)boss后攻擊力和防御力下滑,從備忘錄對象恢復(fù)到大戰(zhàn)前的狀態(tài)。

實現(xiàn):

package mementor;

public class GameRole {
    
    private int attack;
    private int defence;
    
    
    public Memento saveStateMemento() {
        return new Memento(attack ,defence);
    }
    
    public void getStateFromMemento(Memento memento) {
        attack = memento.getAttack();
        defence = memento.getDefence();
    }

    public int getAttack() {
        return attack;
    }

    public void setAttack(int attack) {
        this.attack = attack;
    }

    public int getDefence() {
        return defence;
    }

    public void setDefence(int defence) {
        this.defence = defence;
    }

}

public class Memento {
    
    private int attack;
    private int defence;
    
    public Memento(int attack, int defence) {
        super();
        this.attack = attack;
        this.defence = defence;
    }
    public int getAttack() {
        return attack;
    }
    public int getDefence() {
        return defence;
    }   
}

public class Caretaker {

    private HashMap<String, ArrayList<Memento>> map = new HashMap<>();
    
    public void add(String name,Memento memento) {
        if (!map.containsKey(name)) {
            map.put(name, new ArrayList<>());
        }
        map.get(name).add(memento);
    }
    
    public Memento get(String name,int index) {
        return map.get(name).get(index);
    }
}

public class Client {

    public static void main(String[] args) {
        
        GameRole gameRole1 = new GameRole();
        Caretaker caretaker = new Caretaker();
        
        gameRole1.setAttack(100);   
        caretaker.add(gameRole1.toString(),gameRole1.saveStateMemento());
        System.out.println("當(dāng)前狀態(tài):"+gameRole1.getAttack());
        
        gameRole1.setAttack(88);            
        caretaker.add(gameRole1.toString(),gameRole1.saveStateMemento());
        System.out.println("當(dāng)前狀態(tài):"+gameRole1.getAttack());
        
        gameRole1.getStateFromMemento(caretaker.get(gameRole1.toString(),0));
        System.out.println("恢復(fù)后狀態(tài):"+gameRole1.getAttack());
        System.out.println(gameRole1.toString());
        
        GameRole gameRole2 = new GameRole();
        
        gameRole2.setAttack(10);    
        caretaker.add(gameRole2.toString(),gameRole2.saveStateMemento());
        System.out.println("當(dāng)前狀態(tài):"+gameRole2.getAttack());
        
        gameRole2.setAttack(68);            
        caretaker.add(gameRole2.toString(),gameRole2.saveStateMemento());
        System.out.println("當(dāng)前狀態(tài):"+gameRole2.getAttack());
        
        gameRole2.getStateFromMemento(caretaker.get(gameRole2.toString(),0));
        System.out.println("恢復(fù)后狀態(tài):"+gameRole2.getAttack());
        System.out.println(gameRole2.toString());
    }
}

備忘錄模式的注意事項和細(xì)節(jié)

  1. 給用戶提供了- -種可以恢復(fù)狀態(tài)的機(jī)制,可以使用戶能夠比較方便地回到某個歷史
  2. 實現(xiàn)了信息的封裝,使得用戶不需要關(guān)心狀態(tài)的保存細(xì)節(jié)
  3. 如果類的成員變量過多,勢必會占用比較大的資源,而且每一次保存都會消耗一定的內(nèi)存,這個需要注意
  4. 適用的應(yīng)用場景: 1、后悔藥。2、 打游戲時的存檔。3、 Windows 里的ctri + z。4、IE中的后退。4、 數(shù)據(jù)庫的事務(wù)管理
  5. 為了節(jié)約內(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ù)。

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