忘录模式就是对某个类的状态进行保存下来,等到需要恢复的时候,可以从备忘录中进行恢复。生活中这样的例子经常看到,如备忘电话通讯录,备份操作操作系统,备份数据库等。
  备忘录模式的具体定义是:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以把该对象恢复到原先的状态。

备忘录模式中主要有三类角色:

  • 发起人角色(手机用户):记录当前时刻的内部状态,负责创建和恢复备忘录数据。
  • 备忘录角色:负责存储发起人对象的内部状态,在进行恢复时提供给发起人需要的状态。
  • 管理者角色(数据库):负责保存备忘录对象。
    // 联系人
    public class ContactPerson
    {
        public string Name { get; set; }
        public string MobileNum { get; set; }
    }
    // 发起人
    public class MobileOwner
    {
        public List<ContactPerson> ContactPersons { get; set; }
        public MobileOwner(List<ContactPerson> persons)
        {
            ContactPersons = persons;
        }
        // 创建备忘录,将当期要保存的联系人列表导入到备忘录中
        public ContactMemento CreateMemento()
        {
            return new ContactMemento(new List<ContactPerson>(this.ContactPersons));
        }
        // 将备忘录中的数据备份导入到联系人列表中
        public void RestoreMemento(ContactMemento memento)
        {
            if (memento != null)
            {
                this.ContactPersons = memento.ContactPersonBack;
            }
        }
        public void Show()
        {
            Console.WriteLine(“联系人列表中有{0}个人,他们是:”, ContactPersons.Count);
            foreach (ContactPerson p in ContactPersons)
            {
                Console.WriteLine(“姓名: {0} 号码为: {1}”, p.Name, p.MobileNum);
            }
        }
    }
    // 备忘录
    public class ContactMemento
    {
        public List<ContactPerson> ContactPersonBack { get; set; }
        public ContactMemento(List<ContactPerson> persons)
        {
            ContactPersonBack = persons;
        }
    }
    //数据库
    public class Caretaker
    {
        // 使用多个备忘录来存储多个备份点
        public Dictionary<string, ContactMemento> ContactMementoDic { get; set; }
        public Caretaker()
        {
            ContactMementoDic = new Dictionary<string, ContactMemento>();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            // 创建数据库
            Caretaker caretaker = new Caretaker();
            List<ContactPerson> persons = new List<ContactPerson>()
            {
                new ContactPerson() { Name= “A0”, MobileNum = “123”},
                new ContactPerson() { Name = “A1”, MobileNum = “1234”},
                new ContactPerson() { Name = “A2”, MobileNum = “12345”},
                new ContactPerson() { Name = “A3”, MobileNum = “123456”},
                new ContactPerson() { Name = “A4”, MobileNum = “1234567”}
            };
            MobileOwner mobileOwner = new MobileOwner(persons);
            mobileOwner.Show();
            ModifyDataBase(caretaker, mobileOwner);
            mobileOwner.ContactPersons.RemoveAt(mobileOwner.ContactPersons.Count-1);
            mobileOwner.Show();
            ModifyDataBase(caretaker, mobileOwner);
            mobileOwner.ContactPersons.RemoveAt(mobileOwner.ContactPersons.Count-1);
            mobileOwner.Show();
            ModifyDataBase(caretaker, mobileOwner);
            mobileOwner.ContactPersons.RemoveAt(mobileOwner.ContactPersons.Count-1);
            mobileOwner.Show();
            ModifyDataBase(caretaker, mobileOwner);
            mobileOwner.ContactPersons.RemoveAt(mobileOwner.ContactPersons.Count-1);
            mobileOwner.Show();
            ModifyDataBase(caretaker, mobileOwner);
            mobileOwner.ContactPersons.Add(new ContactPerson() { Name = “小王”, MobileNum = “110” });
            mobileOwner.Show();
            ModifyDataBase(caretaker, mobileOwner);
            Console.WriteLine(“可恢复最后五个存档:输入【0-4】查询”);
            while (true)
            {
                int index = 0;
                try
                {
                    index = Int32.Parse(Console.ReadLine());
                }
                catch
                {
                    Console.WriteLine(“输入的格式错误”);
                }
                ContactMemento contactMentor = null;
                if (index < caretaker.ContactMementoDic.Count &&
                    caretaker.ContactMementoDic.TryGetValue(caretaker.ContactMementoDic.Keys.ElementAt(index), out contactMentor))
                {
                    mobileOwner.RestoreMemento(contactMentor);
                    mobileOwner.Show();
                }
                else
                {
                    Console.WriteLine(“输入的索引大于集合长度!”);
                }
            }
        }
        static void ModifyDataBase(Caretaker caretaker, MobileOwner mobileOwner)
        {
            if (caretaker.ContactMementoDic.Count < 5)
            {
                //直接存入
                caretaker.ContactMementoDic.Add((caretaker.ContactMementoDic.Count).ToString(), mobileOwner.CreateMemento());
            }
            else
            {
                //删除最早的存档
                caretaker.ContactMementoDic.Remove(“0”);
                Dictionary<string, ContactMemento> _newContactMementoDic = new Dictionary<string, ContactMemento>();
                int index = 0;
                foreach (var i in caretaker.ContactMementoDic.Keys)
                {
                    _newContactMementoDic.Add(index.ToString(), caretaker.ContactMementoDic[i]);
                    index++;
                }
                caretaker.ContactMementoDic = _newContactMementoDic;
                //存入
                caretaker.ContactMementoDic.Add((caretaker.ContactMementoDic.Count).ToString(), mobileOwner.CreateMemento());
            }
        }
    }