• 设计模式(十九)—— 备忘录模式


    模式简介


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

    很多时候我们要记录一个对象的内部状态,为了允许用户撤销不确定的操作或从错误中恢复过来。同时,为了不违反封装的原则,而不能暴露其内部状态和实现。想象一下日常生活中我们经常会遇到重置密码的问题,假设账号密码在初始化后,保留一份备忘录以便今后重置时使用,同样的,我们不能将密码暴露给其它对象。这时,可以使用备忘录模式解决这个问题。

    结构分析


    UML类图

    角色说明

    • Memento

    备忘录。存储原发器对象的内部状态,防止原发器以外的对象访问备忘录。

    • Originator

    原发器。提供一个方法创建备忘录,用以记录当前时刻它的内部状态,并提供一个使用备忘录恢复内部状态的方法。

    • Caretaker

    负责人。负责保存备忘录,不能对备忘录的内容进行操作或检查。

    工作原理

    管理器向原发器请求一个备忘录,保留一段时间,将其送回原发器。

    结构代码

    //备忘录
    public class Memento
    {
        private string _state;
        public Memento(string state)
        {
            _state = state;
        }
    
        public string GetState()
        {
            return _state;
        }
    }
    
    //原发器
    public class Originator
    {
        public string State { get; set; }
        public Memento CreateMemento()
        {
            return new Memento(State);
        }
        public void SetMemento(Memento memento)
        {
            Console.WriteLine("Restoring state...");
            State = memento.GetState();
        }
    }
    
    //负责人
    public class Caretaker
    {
        public Memento Memento { get; set; }
    }
    
    //客户端调用
    class Program
    {
        static void Main(string[] args)
        {
            Originator originator = new Originator();
            originator.State = "Off";
            Caretaker caretaker = new Caretaker();
            caretaker.Memento = originator.CreateMemento();
            originator.State = "On";
            originator.SetMemento(caretaker.Memento);
            Console.WriteLine(originator.State);
            Console.ReadLine();
        }
    }   
    

    程序输出:

    示例分析


    本节通过一个重置密码的示例来讲述备忘录模式,首先声明备忘录Memento。

    public class Memento
    {
        public string UserName { get; private set; }
        public string Password { get; private set; }
        public Memento(string userName,string password)
        {
            UserName = userName;
            Password = password;
        }
    }
    

    声明原发器User,包含UserName和Password属性,提供CreateMemento方法创建备忘录,以及SetMemento方法提供重置功能。

    public class User
    {
        public string UserName { get; set; }
        public string Password { get; set; }
        public User(string username,string password)
        {
            this.UserName = username;
            this.Password = password;
        }
        public Memento CreateMemento()
        {
            return new Memento(UserName, Password);
        }
    
        public void SetMemento(Memento memento)
        {
            this.UserName = memento.UserName;
            this.Password = memento.Password;
        }
    }
    
    public class UserMemory
    {
        public Memento Memento { get; set; }
    }
    

    客户端调用,创建jack账号并创建备忘录,随后修改了两次密码,最后使用备忘录进行重置。

    class Program
    {
        static void Main(string[] args)
        {
            User jack = new User("jack", "12345");
            UserMemory memory = new UserMemory();
            memory.Memento = jack.CreateMemento();
            jack.Password = "23456";
            jack.Password = "qwert";
            jack.SetMemento(memory.Memento);
            Console.WriteLine(jack.Password);
            Console.ReadLine();
        }
    }
    

    使用场景


    • 必须保存某个对象在某一时刻的状态,以便以后需要时恢复到该状态。

    • 不希望暴露对象的实现细节以至破坏对象的封装性。

  • 相关阅读:
    [TCP/IP]TCP的三次握手和四次挥手

    思考
    jQuery完整的事件委托(on())
    jQuery队列动画
    jQuery自定义动画
    jQuery淡入淡出
    jQuery滑动动画
    jQuery基本动画
    jQuery基础3
  • 原文地址:https://www.cnblogs.com/Answer-Geng/p/9292773.html
Copyright © 2020-2023  润新知