备忘录模式

回到首页

概述

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态

主要是用来防丢失、撤销、恢复等。在不违背封装原则的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便之后恢复对象为先前的状态。

结构图

 

 

代码实现

备忘录模式

 

发起人

    /// <summary>
    /// 发起人
    /// </summary>
    public class Originator
    {
        private string state;
        public string State
        {
            get { return state; }
            set { state = value; }
        }

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

        public void SetMemento(Memento memento)
        {
            state = memento.State;
        }

        public void Show()
        {
            Console.WriteLine("State=" + state);
        }
    }

备忘录

    /// <summary>
    /// 备忘录
    /// </summary>
    public class Memento
    {
        private string state;

        public Memento(string state)
        {
            this.state = state;
        }

        public string State
        {
            get { return state; }
        }
    }

管理者

    /// <summary>
    /// 管理者
    /// </summary>
    public class Caretaker
    {
        private Memento memento;

        public Memento Memento
        {
            get { return memento; }
            set { memento = value; }
        }
    }

客户端

    class Program
    {
        static void Main(string[] args)
        {
            Originator o = new Originator();
            o.State = "On";
            o.Show();
            Caretaker c = new Caretaker();
            c.Memento = o.CreateMemento();
            o.State = "Off";
            o.Show();
            o.SetMemento(c.Memento);
            o.Show();
            Console.Read();
        }
    }

运行结果

文本备忘录

待备份类

    //待备份类
    public class InputText
    {
        private StringBuilder sb = new StringBuilder();
        public string GetText()
        {
            return sb.ToString();
        }
        public Snapshot CreateSnapshot()
        {
            return new Snapshot(GetText());
        }
        public void Append(string input)
        {
            sb.Append(input);
        }
        public void RestoreSnapshot(Snapshot snapshot)
        {
            this.sb = new StringBuilder();
            this.sb.Append(snapshot.GetText());
        }
    }

备忘录

    /// <summary>
    /// 备忘录
    /// </summary>
    public class Snapshot
    {
        private string text;
        public Snapshot(string text)
        {
            this.text = text;
        }
        public string GetText()
        {
            return this.text;
        }
    }

存储栈

    /// <summary>
    /// 存储栈
    /// </summary>
    public class SnapshotHolder
    {
        private Stack<Snapshot> snapshots = new Stack<Snapshot>();
        public Snapshot PopSnapshot()
        {
            return snapshots.Pop();
        }
        public void PushSnapshot(Snapshot snapshot)
        {
            snapshots.Push(snapshot);
        }
    }

客户端

        static void Main(string[] args)
        {
            SnapshotHolder snapshotHolder = new SnapshotHolder();
            InputText inputText = new InputText();
            inputText.Append("输入值1");
            inputText.Append("输入值2");
            Snapshot snapshot = inputText.CreateSnapshot();
            snapshotHolder.PushSnapshot(snapshot);
            inputText.Append("输入值3");
            Console.WriteLine(inputText.GetText());
            inputText.RestoreSnapshot(snapshotHolder.PopSnapshot());
            Console.WriteLine(inputText.GetText());
            Console.Read();
        }

运行结果

优势

给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。

实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。

简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。

使用场景

需要保存/恢复数据的相关状态场景。

提供一个可回滚的操作。

缺陷

消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。(可以采用低频全量备份,高频增量备份的策略)

Demo

posted @ 2021-11-24 23:10  .NET_CJL  阅读(8)  评论(0编辑  收藏  举报