java-設計模式-備忘錄模式

設計模式-備忘錄模式
    本質:保存和恢復對象狀態(部分狀態)
    不破壞封裝性的前提下,獲取一個對象的內部狀態,並在該對象外保存這個狀態。
    Memento模式比較適用於功能比較複雜的,但需要維護或記錄屬性歷史的類,或者保護的屬性只是衆多屬性中的一小部分。
    典型例子:
        遊戲大戰Boss前會保存記錄。

UML圖:

下面用一個30歲的中年人想穿越回10歲小孩的例子來模擬下這個備忘錄模式。

先來個Person類:

Person有基本的年齡和力量屬性,這個 穿越時,會變化,但是記憶是不會變化的,如果記憶也變化了,那麼就不是穿越了,哈哈。


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Person {
    private int age;//年齡
    private int power;//力量
    private List<String> rememberList = new ArrayList<>();//記憶 這個屬性是不用寫進備忘錄的,即使穿越了也會有的


    public void show(){
        System.out.println("age:"+age+" power:"+power+" remember:"+ Arrays.toString(rememberList.toArray()));
        System.out.println();
    }
    /**
     * 記錄此時此刻
     */
    public PersonMemento record(){
        PersonMemento personMemento = new PersonMemento();
        personMemento.setAge(this.getAge());
        personMemento.setPower(this.getPower());
        return personMemento;
    }

    /**
     * 重新來一次
     * @param personMemento
     */
    public void reback(PersonMemento personMemento){
        this.age = personMemento.getAge();
        this.power = personMemento.getPower();
    }

    //getter and setter

  
}

備忘錄類:

這個類的屬性是Person的部分屬性,用來保存當時的狀態。

問:可以直接用Person類嗎?

答:如果大部門屬性都一樣,是可以的,這時可以用原型模式進行復制。但是如果類屬性特別多,但是需要備忘的數據特別少,那麼就建議使用備忘錄類。


/**
 * 人物備忘錄
 */
public class PersonMemento {
    private int age;
    private int power;

    //getter and setter

}

備忘錄管理者類:

備忘錄 管理者,主要就是 對 備忘錄的 存和拿。


/**
 * 時間之神 備忘錄管理者
 */
public class TimeGod {
    private PersonMemento personMemento;

    //getter and setter


    public PersonMemento getPersonMemento() {
        return personMemento;
    }

    public void setPersonMemento(PersonMemento personMemento) {
        this.personMemento = personMemento;
    }
}

調用者(測試類):


public class Test {
    public static void main(String[] args) {
        TimeGod timeGod = new TimeGod();//時間之神,備忘錄管理者
        System.out.println("10歲 主人公出場了");
        Person person = new Person();
        //年齡10歲 能力15
        person.setAge(10);
        person.setPower(15);
        person.getRememberList().add("那年我10歲,但是能力只有15,不能自己買棒棒糖給自己。\n");
        System.out.print("現在狀態:" );
        person.show();

        //
        System.out.println("時間之神默默記錄下了當時的情況");
        timeGod.setPersonMemento(person.record());

        System.out.println("主人公長大了");
        person.setAge(30);
        person.setPower(200);
        person.getRememberList().add("現在我已經30歲了,有很大的能力是,可以買很多棒棒糖了。\n");
        System.out.print("現在狀態:" );
        person.show();

        System.out.println("他向時間之神許了個願望,想回到10歲,時間之神答應了");
        person.reback(timeGod.getPersonMemento());

        System.out.println("回到過去...");
        System.out.print("現在狀態:" );
        person.show();
    }
}

測試輸出結果:

10歲 主人公出場了
現在狀態:age:10 power:15 remember:[那年我10歲,但是能力只有15,不能自己買棒棒糖給自己。
]

時間之神默默記錄下了當時的情況
主人公長大了
現在狀態:age:30 power:200 remember:[那年我10歲,但是能力只有15,不能自己買棒棒糖給自己。
, 現在我已經30歲了,有很大的能力是,可以買很多棒棒糖了。
]

他向時間之神許了個願望,想回到10歲,時間之神答應了
回到過去...
現在狀態:age:10 power:15 remember:[那年我10歲,但是能力只有15,不能自己買棒棒糖給自己。
, 現在我已經30歲了,有很大的能力是,可以買很多棒棒糖了。
]

 

優化:

上面的例子備忘錄只有一個,可以做成多個,在關鍵節點都進行狀態保存。

 

上訴說到原型模式,如果你還對此模式不是很瞭解,可以查閱筆者的博客:

https://blog.csdn.net/xiaoluo5238/article/details/104636157

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