1. 程式人生 > 實用技巧 >設計模式 - 16)備忘錄模式

設計模式 - 16)備忘錄模式

打遊戲的時候,存檔;
場景:儲存某個時刻的狀態,一般用於針對的儲存部分屬性,如果是所有,直接呼叫 Clone 即可。

graph LR 角色Originator-->存檔Memento 管理存檔CareTaker-->存檔Memento
/// <summary>
/// 角色類
/// </summary>
class Originator
{
    int _attackNum;
    public int AttackNum
    {
        get { return _attackNum; }
        set { _attackNum = value; }
    }

    ...

    public void Show()
    {
        Console.WriteLine(string.Format("攻擊力:{0},防禦力:{1},生命力:{2}", AttackNum, DefenseNum, LifeNum));
    }

    public void InitStance()
    {
        this._attackNum = 100;
        this._defenseNum = 100;
        this._lifeNum = 100;
    }

    public void hart()
    {
        Console.WriteLine("角色受到傷害");
        this._attackNum -= 10;
        this._defenseNum -= 10;
        this._lifeNum -= 10;
    }
        
    /// <summary>
    /// 儲存當前存檔
    /// </summary>
    /// <returns></returns>
    public Memento SaveState()
    {
        return new Memento(_attackNum, _defenseNum, _lifeNum);
    }
    
    /// <summary>
    /// 載入某個存檔
    /// </summary>
    /// <param name="memento"></param>
    public void RecoverState(Memento memento)
    {
        this._attackNum = memento.AttackNum;
        this._defenseNum = memento.DefenseNum;
        this._lifeNum = memento.LifeNum;
    }
}

/// <summary>
/// 存檔類
/// </summary>
class Memento
{
    int _attackNum;
    public int AttackNum
    {
        get { return _attackNum; }
        set { _attackNum = value; }
    }
    ...
    
    public Memento(int attack, int defense, int life)
    {
        this._attackNum = attack;
        this._defenseNum = defense;
        this._lifeNum = life;
    }
}

/// <summary>
/// 管理存檔類
/// </summary>
class CareTaker
{
    Memento _memento;
    public Memento Memento
    {
        get { return _memento; }
        set { _memento = value; }
    }
}

// 業務程式碼:
// 備忘管理
CareTaker ct = new CareTaker();

// 角色
Originator og = new Originator();
// 角色初始化
og.InitStance();
og.Show();

// 角色受到傷害
og.hart();
og.Show();
ct.Memento = og.SaveState();

// 角色繼續暴擊
og.hart();
og.Show();
og.hart();
og.Show();

// 扛不動了,重新載入一下存檔
og.RecoverState(ct.Memento);
            
og.Show();

後面如果需要管理的存檔多了:

interface IMemento { }

class Memento : IMemento {...}

class CareTaker
{
    Dictionary<string, IMemento> MementoDic = new Dictionary<string, IMemento>();

    public Memento GetMemento(string key)
    {
        Memento result = null;
        if (MementoDic.ContainsKey(key))
        {
            result = (Memento)MementoDic[key];
        }
        return result;
    }

    public void AddMemento(string key, IMemento memento)
    {
        if (MementoDic.ContainsKey(key))
        {
            MementoDic[key] = memento;
        }
        else
        {
            MementoDic.Add(key, memento);
        }
    }
}

// 業務程式碼:
CareTaker ct = new CareTaker();

// 角色
Originator og = new Originator();

string mementoName = "og" + DateTime.Now.ToString();
// 存檔
ct.AddMemento(mementoName, og.SaveState();

// 載入存檔
og.RecoverState(ct.GetMemento(mementoName));