1.定义

Without violating encapsulation,capture and externalize an object's internal state so that the object can be restored to this state later.(在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之处保存这个状态。这样以后就可将该对象恢复到原先保持的状态)

Originator发起人角色:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备份数据。

Memento备忘录角色:负责存储Originator发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。

Caretaker备忘录管理员角色:对备忘录进行管理、保存和提供备忘录。

2.代码实现

    /// <summary>
    /// 发起人角色
    /// </summary>
    public class Originator
    {
        private string _state;

        public void SetState(string state)
        {
            _state = state;
        }

        public string GetState()
        {
            return _state;
        }

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

        public void RestoreMemento(Memento memento)
        {
            this._state = memento.GetState();
        }
    }
    /// <summary>
    /// 备忘录角色
    /// </summary>
    public class Memento
    {
        private string _state;

        public Memento(string state)
        {
            _state = state;
        }

        public void SetState(string state)
        {
            _state = state;
        }

        public string GetState()
        {
            return _state;
        }
    }
    /// <summary>
    /// 备忘录管理员
    /// </summary>
    public class CareTaker
    {
        private Memento _memento;

        public void SetMemento(Memento memento)
        {
            _memento = memento;
        }

        public Memento GetMemento()
        {
            return _memento;
        }
    }
    /// <summary>
    /// 场景类
    /// </summary>
    class Program
    {
        private static void Main(string[] args)
        {
            Originator originator = new Originator();

            CareTaker careTaker = new CareTaker();

            careTaker.SetMemento(originator.CreateMemento());

            originator.RestoreMemento(careTaker.GetMemento());

            Console.ReadKey();
        }

    }

3.更好的封装

备份是不能被修改的,也就是说需要缩小备份出的备忘录的阅读权限,保证只能是发起人可读就成了,那怎么才能做到这一点呢?使用内置类。

    /// <summary>
    /// 发起人角色
    /// </summary>
    public class Originator : ICloneable
    {
        private string _state;

        public void SetState(string state)
        {
            _state = state;
        }

        public string GetState()
        {
            return _state;
        }

        public IMemento CreateMemento()
        {
            return new Memento(_state);
        }

        public void RestoreMemento(IMemento memento)
        {
            this._state = ((Memento) memento).GetState();
        }

        public object Clone()
        {
            return MemberwiseClone();
        }

        /// <summary>
        /// 备忘录角色,全是Private访问权限,也就是说除了发起人之外,其他用户无法访问备忘录的数据。通过接口关联给其他类使用。
        /// </summary>
        private class Memento : IMemento
        {
            private string _state;

            public Memento(string state)
            {
                _state = state;
            }

            public void SetState(string state)
            {
                _state = state;
            }

            public string GetState()
            {
                return _state;
            }
        }
    }
    /// <summary>
    /// 备忘录角色
    /// </summary>
    public interface IMemento
    {
       
    }
    /// <summary>
    /// 备忘录管理员
    /// </summary>
    public class CareTaker
    {
        private IMemento _memento;

        public void SetMemento(IMemento memento)
        {
            _memento = memento;
        }

        public IMemento GetMemento()
        {
            return _memento;
        }
    }

4.备忘录模式的扩展

(1)clone方式的备忘录

    /// <summary>
    /// 发起人兼备忘录角色
    /// </summary>
    public class Originator : ICloneable
    {
        private string _state;
        private Originator _backUp;

        public void SetState(string state)
        {
            _state = state;
        }

        public string GetState()
        {
            return _state;
        }

        public void CreateMemento()
        {
            _backUp = (Originator)Clone();
        }

        public void RestoreMemento()
        {
            this._state = _backUp.GetState();
        }

        public object Clone()
        {
            return MemberwiseClone();
        }
    }

    /// <summary>
    /// 场景类
    /// </summary>
    class Program
    {
        private static void Main(string[] args)
        {
            Originator originator = new Originator();

            originator.SetState("hello");

            Console.WriteLine(originator.GetState());

            originator.CreateMemento();

            originator.SetState("hello GG");

            Console.WriteLine(originator.GetState());

            originator.RestoreMemento();

            Console.WriteLine(originator.GetState());

            Console.ReadKey();
        }

    }

(2)多备份的备忘录  

    /// <summary>
    /// 备忘录管理员
    /// </summary>
    public class CareTaker
    {
        private readonly List<KeyValuePair<string, Memento>> _mementos = new List<KeyValuePair<string, Memento>>();

        public void SetMemento(string idx, Memento memento)
        {
            _mementos.Add(new KeyValuePair<string, Memento>(idx, memento));
        }

        public Memento GetMemento(string idx)
        {
            KeyValuePair<string, Memento> mementoKv = _mementos.FirstOrDefault(item => item.Key.Equals(idx));

            return mementoKv.Value;
        }
    }                                                                                        
posted on 2015-06-10 17:21  JustYong  阅读(163)  评论(0)    收藏  举报