设计模式之备忘录模式

266 阅读1分钟

定义

备忘录模式(Memento Pattern) 也称快照模式(Snapshot Pattern),指在不破坏封装的前提下,保存某个对象的状态,意思就是可以在某个时间段或者某个操作后将对象的状态保存下来,以后就可以恢复到原先保存的状态。

举个例子:游戏存档,假设有十个存档位,用户操作存档后存档位则生成一个保存了当前游戏状态的存档,以后用户就可以恢复某个存档保存的状态。

三个角色

  • 发起人(Originator):负责创建一个备忘录,记录自己需要保存的状态,可以回滚状态(tips:需要保存状态的对象)
  • 备忘录(Memento):用于存储Originator的状态,且可以防止Originator以外的对象访问
  • 备忘录管理员(Caretaker):存储和获取备忘录(tips:例如使用栈存储备忘录对象,实现撤销功能)

案例

需要实现一个可撤销操作的功能。

需要保存状态的对象类(Originator):

class Originator
    {
        private string _id;
        private string _name;
        private string _age;
        public Originator(string name, string age)
        {
            this._name = name;
            this._age = age;
        }
        public string GetName()
        {
            return _name;
        }
        public string GetAge()
        {
            return _age;
        }
        public void SetName(string name)
        {
            this._name = name;
        }
        public void SetAge(string age)
        {
            this._age = age;
        }
        public Memento Save()
        {
            Memento memento = new Memento(_name, _age);
            return memento;
        }
        public void Rollback(Memento memento)
        {
            this._name = memento.GetName();
            this._age = memento.GetAge();
        }

        public override string ToString()
        {
            return $"Name:{_name}, Age:{_age}";
        }
    }

备忘录类(Memento):

class Memento
    {
        private string _id;
        private string _name;
        private string _age;
        public Memento(string name, string age)
        {
            this._name = name;
            this._age = age;
        }
        public string GetName()
        {
            return _name;
        }
        public string GetAge()
        {
            return _age;
        }
    }

备忘录管理员类(Caretaker):

class Caretaker
    {
        private Stack<Memento> stack = new();
        public void AddStack(Memento memento)
        {
            stack.Push(memento);
        }
        public Memento GetMemento()
        {
            return stack.Pop();
        }
    }

测试:

class Program
    {
        static void Main(string[] args)
        {
            // 管理员对象
            Caretaker caretaker = new Caretaker();
            Originator originator = new Originator("Tom", "18");
            Memento memento = originator.Save();
            caretaker.AddStack(memento);
            Console.WriteLine("----->新建对象<-----");
            Console.WriteLine(originator);


            originator.SetName("Jacky");
            originator.SetAge("28");
            Memento memento2 = originator.Save();
            caretaker.AddStack(memento2);
            Console.WriteLine("----->修改<-----");
            Console.WriteLine(originator);

            caretaker.GetMemento();
            Memento rollBackMemento1 = caretaker.GetMemento();
            originator.Rollback(rollBackMemento1);
            Console.WriteLine("----->回滚到修改之前<-----");
            Console.WriteLine(originator);
        }
    }

运行结果:

image.png