C#设计模式之备忘录模式

备忘录模式


本篇博客将介绍备忘录模式,备忘录模式是软件系统中的“月光宝盒”,它提供了一种对象状态的撤销实现机制,当系统中一个对象需要恢复某一个历史状态时,就可以使用备忘录模式进行设计。

模式分类

行为型设计模式。

模式产生的原因

在使用软件的过程中大家难免会产生一些误操作,例如不小心删除了某些文字或者图片,为了使软件更加人性化,对于这些误操作,需要提供一种类似于后悔药的机制,让软件系统可以回到误操作之前的状态,因此需要保存用户每一次操作时系统的状态,一旦出现误操作,只需要将存储的历史状态取出即可回到之前的状态。备忘录模式正是为此类问题而生的。

模式类图

在这里插入图片描述

由上图可知,备忘录模式有以下3个对象构成:

Originator(原发器):

原发器是一个普通类,一般我们会让需要备份的类作为原发器存在,原发器可以通过创建一个备忘录来保存当前的系统状态,也可以使用备忘录来恢复其内部状态。

Memento(备忘录):

备忘录用于存储原发器的内部状态,通常备忘录的设计会参考原发器的设计。需要注意的是除过Caretaker类和Originator类之外,系统其他类不可以访问备忘录的内容。

Caretaker(负责人类):

负责人类负责管理系统的备忘录。

代码实现

我们通过备忘录模式模拟word的撤销和重做功能。

NotePad原发器:

using System;

namespace Memento.Memento.Question5
{
    public class NotePad
    {
        private string _content;

        public void ChangeContent(string content)
        {
            _content = content;
            SaveContent(content);
            Show();
        }

        public void UndoContent()
        {
            _content = Caretaker.GetInstance.UndoPop().GetContent();
            Show();
        }

        public void RedoContent()
        {
            _content = Caretaker.GetInstance.RedoPop().GetContent();
            Show();
        }

        public void Show()
        {
            Console.WriteLine(_content);
        }

        private void SaveContent(string content)
        {
            Caretaker.GetInstance.UndoPush(new Memento(content));
        }
    }
}

Memento备忘录:

namespace Memento.Memento.Question5
{
    public class Memento
    {
        private string _content;

        public Memento(string content)
        {
            _content = content;
        }

        public void SetContent(string content)
        {
            _content = content;
        }

        public string GetContent()
        {
            return _content;
        }
    }
}

Caretaker负责人类:

using System;
using System.Collections.Generic;

namespace Memento.Memento.Question5
{
    public class Caretaker
    {
        private static Caretaker _instance;

        public static Caretaker GetInstance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new Caretaker();
                }

                return _instance;
            }
        }
        
        private  Stack<Memento> _undoStack = new Stack<Memento>();
        private  Stack<Memento> _redoStack = new Stack<Memento>();

        public void UndoPush(Memento memento)
        {
            _undoStack.Push(memento);
        }

        public Memento UndoPop()
        {
            if (_undoStack.Count == 0)
            {
                Console.WriteLine($"无法继续撤销");
            }
            Memento memento = _undoStack.Pop();
            RedoPush(memento);
            return memento;
        }

        public void RedoPush(Memento memento)
        {
            _redoStack.Push(memento);
        }

        public Memento RedoPop()
        {
            if (_redoStack.Count == 0)
            {
                Console.WriteLine($"无法继续重做");
            }
            Memento memento = _redoStack.Pop();
            UndoPush(memento);
            return memento;
        }
    }
}

Program类:

using System;
using Memento.Memento.Question5;

namespace Memento
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            NotePad notePad = new NotePad();
            notePad.ChangeContent("123");
            notePad.ChangeContent("1234");
            notePad.UndoContent();
            notePad.UndoContent();
            notePad.RedoContent();
            notePad.RedoContent();
            notePad.ChangeContent("12345");
            notePad.ChangeContent("123456");
            notePad.UndoContent();
            notePad.UndoContent();
            notePad.ChangeContent("1234567");
            notePad.ChangeContent("12345678");
            notePad.UndoContent();
            notePad.UndoContent();
            notePad.UndoContent();
            notePad.UndoContent();
        }
    }
}

原理是这么一个原理,但上述实现是有一点小问题的,每次重做或者撤销的时候,其顶层存放的就是当前状态。

备忘录模式总结

备忘录模式的优点:

  1. 备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便的回到一个特定的历史状态。
  2. 备忘录模式实现了对信息的封装,一个备忘录对象是一种原发器对象的状态表示,不会被其他代码所改动,一般在C#中为了实现这点我们通常会通过程序集进行区分。

备忘录模式的缺点:

  1. 经典备忘录模式的计算机资源消耗较大。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值