備忘錄模式

1. 遊戲存進度

B: 代碼無錯未必優。
A: 問題主要在於這客戶端的調用。應爲這樣寫就把整個遊戲角色的細節暴露給了客戶端,你客戶端職責就太大了。
A: 顯然,遊戲角色的存取細節封裝起來,並且最好封裝在外部的類當中。以體現職責分離。this

2. 備忘錄模式

在不破壞封裝的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態。這樣之後就能夠將該對象恢復到原先保存的狀態。

圖1
B: 若是咱們不須要保存所有的信息?
A: 只是部分,那麼就應該有一個獨立的備忘錄類Memento,它只擁有須要保存的信息的屬性。spa

3. 備忘錄基本代碼

class Program
{
    static void Main(string[] args)
    {

        Originator o = new Originator();
        o.State = "On";
        o.Show();

        Caretaker c = new Caretaker();
        c.Memento = o.CreateMemento();

        o.State = "Off";
        o.Show();

        o.SetMemento(c.Memento);
        o.Show();

        Console.Read();

    }
}

class Originator
{
    private string state;
    public string State
    {
        get { return state; }
        set { state = value; }
    }

    public Memento CreateMemento()
    {
        return (new Memento(state));
    }

    public void SetMemento(Memento memento)
    {
        state = memento.State;
    }

    public void Show()
    {
        Console.WriteLine("State=" + state);
    }
}

class Memento
{
    private string state;

    public Memento(string state)
    {
        this.state = state;
    }

    public string State
    {
        get { return state; }
    }
}

class Caretaker
{
    private Memento memento;

    public Memento Memento
    {
        get { return memento; }
        set { memento = value; }
    }
}

B: 就是把保存的細節封裝在了Memento了,哪一天要更改保存的細節也不用影響客服端了。
A: Memento模式比較適合於功能比較複雜的,但須要維護或記錄屬性歷史的類,或者須要保存的屬性只是衆多屬性中的一小部分,Origniator能夠根據保存的Memento信息還原到前以狀態。
A: 若是在某個系統中使用命令模式,須要實現命令的撤銷功能,那麼命令模式可使用備忘錄模式來存儲可撤銷操做的狀態。保存在對象之外的地方,可是必須有對象本身讀取,這時,使用備忘錄能夠把複雜的對象內部信息對其餘的對象屏蔽起來,從而能夠恰當的保持封裝的邊界。
B: 當角色的狀態改變的時候,有可能這個狀態無效,這時候就可使用暫時存儲起來的備忘錄將狀態復原。code

4. 遊戲進度備忘

圖2

class Program
{
    static void Main(string[] args)
    {

        //大戰Boss前
        GameRole lixiaoyao = new GameRole();
        lixiaoyao.GetInitState();
        lixiaoyao.StateDisplay();

        //保存進度
        RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
        stateAdmin.Memento = lixiaoyao.SaveState();

        //大戰Boss時,損耗嚴重
        lixiaoyao.Fight();
        lixiaoyao.StateDisplay();

        //恢復以前狀態
        lixiaoyao.RecoveryState(stateAdmin.Memento);

        lixiaoyao.StateDisplay();


        Console.Read();

    }
}

class GameRole
{
    //生命力
    private int vit;
    public int Vitality
    {
        get { return vit; }
        set { vit = value; }
    }

    //攻擊力
    private int atk;
    public int Attack
    {
        get { return atk; }
        set { atk = value; }
    }

    //防護力
    private int def;
    public int Defense
    {
        get { return def; }
        set { def = value; }
    }

    //狀態顯示
    public void StateDisplay()
    {
        Console.WriteLine("角色當前狀態:");
        Console.WriteLine("體力:{0}", this.vit);
        Console.WriteLine("攻擊力:{0}", this.atk);
        Console.WriteLine("防護力:{0}", this.def);
        Console.WriteLine("");
    }

    //保存角色狀態
    public RoleStateMemento SaveState()
    {
        return (new RoleStateMemento(vit, atk, def));
    }

    //恢復角色狀態
    public void RecoveryState(RoleStateMemento memento)
    {
        this.vit = memento.Vitality;
        this.atk = memento.Attack;
        this.def = memento.Defense;
    }


    //得到初始狀態
    public void GetInitState()
    {
        this.vit = 100;
        this.atk = 100;
        this.def = 100;
    }

    //戰鬥
    public void Fight()
    {
        this.vit = 0;
        this.atk = 0;
        this.def = 0;
    }
}

//角色狀態存儲箱
class RoleStateMemento
{
    private int vit;
    private int atk;
    private int def;

    public RoleStateMemento(int vit, int atk, int def)
    {
        this.vit = vit;
        this.atk = atk;
        this.def = def;
    }

    //生命力
    public int Vitality
    {
        get { return vit; }
        set { vit = value; }
    }

    //攻擊力
    public int Attack
    {
        get { return atk; }
        set { atk = value; }
    }

    //防護力
    public int Defense
    {
        get { return def; }
        set { def = value; }
    }
}

//角色狀態管理者
class RoleStateCaretaker
{
    private RoleStateMemento memento;

    public RoleStateMemento Memento
    {
        get { return memento; }
        set { memento = value; }
    }
}

A: 若是狀態數據很大不少,那麼在資源的消耗上,備忘錄對象會很是耗內存。對象

相關文章
相關標籤/搜索