C#设计模式:备忘录模式(Memento Pattern)

一,C#设计模式:备忘录模式(Memento Pattern)

1、发起人角色(Originator):记录当前时刻的内部状态,负责创建和恢复备忘录数据。负责创建一个备忘录Memento,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator【发起人】可以根据需要决定Memento【备忘录】存储自己的哪些内部状态。
2、备忘录角色(Memento):负责存储发起人对象的内部状态,在进行恢复时提供给发起人需要的状态,并可以防止Originator以外的其他对象访问备忘录。备忘录有两个接口:Caretaker【管理角色】只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator【发起人】却可看到备忘录的宽接口,允许它访问返回到先前状态所需要的所有数据。
3、管理者角色(Caretaker):负责保存备忘录对象。负责备忘录Memento,不能对Memento的内容进行访问或者操作。

二,代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace _22.备忘录模式
{
    
    /// <summary>
    /// 部门--需要备份的数据,是状态数据,没有操作
    /// </summary>
    public sealed class Dept
    {
        /// <summary>
        /// 部门
        /// </summary>
        public string DeptName { get; set; }

        /// <summary>
        /// 人数
        /// </summary>
        public string Number { get; set; }
    }

    /// <summary>
    /// 发起人--相当于【发起人角色】Originator
    /// </summary>
    public sealed class DeptBackOriginator
    {
        // 发起人需要保存的内部状态
        private List<Dept> _deptList;

        public List<Dept> DeptList
        {
            get
            {
                return this._deptList;
            }

            set
            {
                this._deptList = value;
            }
        }
        /// <summary>
        /// 初始化需要备份的部门
        /// </summary>
        /// <param name="deptList"></param>
        public DeptBackOriginator(List<Dept> deptList)
        {
            if (deptList != null)
            {
                this._deptList = deptList;
            }
            else
            {
                throw new ArgumentNullException("参数不能为空!");
            }
        }

        /// <summary>
        /// 创建备忘录对象实例,将当期要保存的联系人列表保存到备忘录对象中
        /// </summary>
        /// <returns></returns>
        public DeptMemento CreateMemento()
        {
            return new DeptMemento(new List<Dept>(this._deptList));
        }

        /// <summary>
        /// 将备忘录中的数据备份还原到部门列表中
        /// </summary>
        /// <param name="memento"></param>
        public void RestoreMemento(DeptMemento memento)
        {
            this.DeptList = memento.DeptListBack;
        }
        /// <summary>
        /// 显示备份包含的数据
        /// </summary>
        public void Show()
        {
            Console.WriteLine("部门列表中共有{0}个部门,他们是:", DeptList.Count);
            foreach (Dept p in DeptList)
            {
                Console.WriteLine("部门: {0} 人数: {1}", p.DeptName, p.Number);
            }
        }
    }

    /// <summary>
    /// 备忘录对象,用于保存状态数据,保存的是当时对象具体状态数据--相当于【备忘录角色】Memeto
    /// </summary>
    public sealed class DeptMemento
    {
        /// <summary>
        /// 保存发起人创建的部门数据
        /// </summary>
        public List<Dept> DeptListBack { get; private set; }

        public DeptMemento(List<Dept> deptList)
        {
            DeptListBack = deptList;
        }
    }

    /// <summary>
    /// 管理角色,它可以管理【备忘录】对象,如果是保存多个【备忘录】对象,当然可以对保存的对象进行增、删等管理处理---相当于【管理者角色】Caretaker
    /// </summary>
    public sealed class MementoCaretaker
    {
        /// <summary>
        /// 如果想保存多个【备忘录】对象,通过字典或者堆栈来保存
        /// </summary>
        public Dictionary<string, DeptMemento> DeptMementoDictionary { get; set; }
        /// <summary>
        /// 单个备份点
        /// </summary>
        public DeptMemento DeptMemento { get; set; }
        public MementoCaretaker()
        {
            DeptMementoDictionary = new Dictionary<string, DeptMemento>();
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Dept> dept = new List<Dept>()
            {
                new Dept() { DeptName="技术部", Number = "15987487456"},
                new Dept() { DeptName="人事部", Number = "15987487457"},
                new Dept() { DeptName="产品部", Number = "15987487458"}
            };

            #region 单个备份点

            //手机名单发起人
            DeptBackOriginator mobileOriginator = new DeptBackOriginator(dept);
            mobileOriginator.Show();

            // 创建备忘录并保存备忘录对象
            MementoCaretaker manager = new MementoCaretaker();
            manager.DeptMemento = mobileOriginator.CreateMemento();

            ///创建第一个备份点
            manager.DeptMementoDictionary.Add("One", mobileOriginator.CreateMemento());

            // 更改发起人联系人列表
            Console.WriteLine("----移除最后一个联系人--------");
            mobileOriginator.DeptList.RemoveAt(2);
            mobileOriginator.Show();

            ///创建第二个备份点
            Thread.Sleep(1000); //等待10秒
            manager.DeptMementoDictionary.Add("Two", mobileOriginator.CreateMemento());

            // 恢复到原始状态
            Console.WriteLine("-------恢复联系人列表------");
            mobileOriginator.RestoreMemento(manager.DeptMemento);
            mobileOriginator.Show();
            #endregion

            #region 多个备份点
            Console.WriteLine("-------输出两个备份点------");
            ////输出备份点
            foreach (var item in manager.DeptMementoDictionary)
            {
                mobileOriginator.RestoreMemento(item.Value);
                mobileOriginator.Show();
            }
            Console.WriteLine("-------恢复到第一个备份点------");
            mobileOriginator.RestoreMemento(manager.DeptMementoDictionary["One"]);
            mobileOriginator.Show();
            Console.WriteLine("-------恢复到第二个备份点------");
            mobileOriginator.RestoreMemento(manager.DeptMementoDictionary["Two"]);
            mobileOriginator.Show();
            #endregion

            Console.Read();
        }
    }
}

 

posted @ 2019-10-16 11:46  叶丶梓轩  阅读(326)  评论(0编辑  收藏  举报