行为型模式 - 备忘录模式Memento

news2024/9/28 13:29:02

学习而来,代码是自己敲的。也有些自己的理解在里边,有问题希望大家指出。

模式的定义与特点

      在备忘录模式(Memento Pattern)下,为的是在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。

模式的优点

  • 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
  • 实现了信息的封装,使得用户不需要关心状态的保存细节。

模式的缺点

  • 消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。
  • 为了符合迪米特原则,还要增加一个管理备忘录的类。

举例使用场景

      我们写代码的时候,写着写着发现有问题,只好Ctrl+Z或者Command+Z撤回;又好像是游戏中的存档问题;也像是Git和SVN的版本控制;再或关卡编辑器。

using DesignPattern.ChainofResponsibilityPattern;
using DesignPattern.MementoPattern;
using DesignPattern.ObserverPattern;
using DesignPattern.VisitorPattern;
using System;
using System.Collections.Generic;

namespace DesignPattern
{
    internal class Program
    {
        static void Main(string[] args)
        {
            MementoHelper();
        }

        #region Pattern - Memento
        static void MementoHelper()
        {
            Originator _originator = new Originator();
            CareTaker _careTaker = new CareTaker();
            _originator.SetInfo("Name 1", 10);
            _careTaker.Add(_originator.SaveInfoToMemento());
            _originator.SetInfo("Name 2", 18);
            _originator.SetInfo("Name 3", 25);
            _careTaker.Add(_originator.SaveInfoToMemento());
            _originator.SetInfo("Name 4", 80);

            Console.WriteLine("当前信息为: name = " + _originator.GetName() + ", age = " + _originator.GetAge());
            _originator.GetInfoFromMemento(_careTaker.Get(0));
            Console.WriteLine("第一次保存信息为: name = " + _originator.GetName() + ", age = " + _originator.GetAge());
            _originator.GetInfoFromMemento(_careTaker.Get(1));
            Console.WriteLine("第二次保存信息为: name = " + _originator.GetName() + ", age = " + _originator.GetAge());
            Console.ReadLine();
        }
        #endregion
    }
}

//====================================================================================================================


namespace DesignPattern.MementoPattern
{
    /// <summary>
    /// 备忘录
    /// 包含了要被恢复的对象的状态
    /// </summary>
    public class Memento
    {
        //也可以为别的内容,eg: 一个class
        private string m_name;
        private int m_age;

        public Memento(string name, int age)
        {
            this.m_name = name;
            this.m_age = age;
        }

        public string GetName()
        {
            return m_name;
        }
        public int GetAge()
        {
            return m_age;
        }
    }

    /// <summary>
    /// 管理人
    /// 负责从 Memento 列表中恢复 Memento 存储对象到某一状态。
    /// </summary>
    public class CareTaker
    {
        public CareTaker()
        {
            m_mementoList = new List<Memento>();
        }

        private List<Memento> m_mementoList;

        public void Add(Memento state)
        {
            m_mementoList.Add(state);
        }

        public Memento Get(int index)
        {
            return m_mementoList[index];
        }
    }
    
    /// <summary>
    /// 发起人,可以是被存储对象,也可以是被存储对象的class.
    /// 创建 Memento 并在被创建的 Memento 对象中存储 该被存储的内容
    /// </summary>
    public class Originator
    {
        private string m_name;
        private int m_age;

        public void SetInfo(string name, int age)
        {
            this.m_name = name;
            this.m_age = age;
        }

        public string GetName()
        {
            return m_name;
        }
        public int GetAge()
        {
            return m_age;
        }

        public Memento SaveInfoToMemento()
        {
            return new Memento(m_name, m_age);
        }

        public void GetInfoFromMemento(Memento Memento)
        {
            m_name = Memento.GetName();
            m_age = Memento.GetAge();
        }
    }
}

 


希望大家:点赞,留言,关注咯~    
😘😘😘😘

唠家常

今日分享结束啦,小伙伴们你们get到了么,你们有没有更好的办法呢,可以评论区留言分享,也可以加QQ:841298494,大家一起进步。

  • 客官,看完get之后记得点赞哟!
  • 小伙伴你还想要别的知识?好的呀,分享给你们😄

今日推荐

  • 博客杂货铺
  • GoF23 种设计模式的分类和功能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/139515.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++ Primer】阅读笔记(2):const | constexpr | 类型别名 |auto

目录 简介const指针顶层const与底层const常量表达式constexpr类型别名auto参考结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过…

CTF中的PHP特性函数(下)

前言 上篇文章讲的进阶一些的PHP特性不知道大家吸收的怎么样了&#xff0c;今天作为本PHP特性函数的最后一篇&#xff0c;我也会重点介绍一些有趣的PHP特性以及利用方法&#xff0c;下面开始我们今天的内容分享。 parse_str parse_str()这个函数会把查询字符串解析到变量中。…

二叉树——链式存储

✅<1>主页&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;数据结构——二叉树 &#x1f525;<3>创作者&#xff1a;我的代码爱吃辣 ☂️<4>开发环境&#xff1a;Visual Studio 2022 &#x1f4ac;<5>前言&#xff1a;上期讲了…

LinkedList与链表(一)(非循环单向链表)

ArrayList的缺陷通过ArrayList上节课的学习&#xff0c;我们了解到如果ArrayList要删除或插入一个元素&#xff0c;后面的元素都要进行移动&#xff0c;时间复杂度为O(n),效率比较低&#xff0c;因此ArrayList不适合做任意位置的插入和删除操作比较多的场景。因此java集合又引入…

Python if __name__ == “__main__“ 用法

文章目录1 前言2 原理3 __name__变量的作用参考1 前言 在很多Python程序中&#xff0c;我们都会遇到if __name__ "__main__"的情况&#xff0c;却不知道为何要这样做 在很多编程语言中&#xff0c;如C、Java等&#xff0c;都需要程序的入口&#xff0c;一般都是ma…

MySql锁机制(全网最全、最详细、最清晰)

1、MySql锁机制 锁机制的作用&#xff1a; 解决因为资源共享&#xff0c;而造成的并发问题。 没有锁机制时&#xff1a; 例如一号用户和二号用户都要去买同一件商品&#xff08;假如这件商品是一件衣服&#xff09;&#xff0c;一号用户手速稍微快了一些&#xff0c;于是就…

从事软件测试需要学自动化么

相信许多对软件测试有过一点了解的人&#xff0c;对自动化都不会感到陌生。我们常常会听到一定软件测试人员一定要学自动化的说法&#xff0c;那么很多人都会有这样的疑问&#xff0c;从事软件测试为什么要学自动化&#xff1f;事实上&#xff0c;如今只会功能测试的从业者往往…

光波导成为AR眼镜迭代新趋势,二维扩瞳几何光波导潜力彰显

关注AR眼镜的朋友可能都会发现&#xff0c;近期新品迭代的一个趋势是持续在小型化、轻量化方向演进。与一年前光学方案主要以BirdBath不同的是&#xff0c;消费级AR眼镜正快速向光波导方案探索和转变。这一点在最近发布的众多新品AR眼镜中就能明显的感受到&#xff0c;以视享G5…

堆排序 TopK 优先级队列的部分源码 JAVA对象的比较

一.堆排序:我们该如何借助堆来对数组的内容来进行排序呢&#xff1f; 假设我们现在有一个数组&#xff0c;要求从小到大进行排序&#xff0c;我们是需要进行建立一个大堆还是建立一个小堆呢&#xff1f; 1)我的第一步的思路就是建立一个小堆&#xff0c;因为每一次堆顶上面的元…

MGRE和ospf的综合运用

目录实验需求知识点实验过程一&#xff0c;在R1 R2 R3中的MGRE搭建二&#xff0c;在R1 R4 R5中的MGRE搭建三&#xff0c;整个内网的ospf协议实验需求 一 题目要求 1&#xff0c;R6为ISP代表运营商&#xff0c;只能配置ip地址&#xff0c;R1-R5环回 代表私有网段 2&#xff0c…

【Linux】顶级编辑器Vim的基本使用及配置

&#x1f451;作者主页&#xff1a;进击的安度因 &#x1f3e0;学习社区&#xff1a;进击的安度因&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;Linux 文章目录一、前言二、vim基本概念三、vim 基本操作1、模式切换2、命令模式3、插入模式4、底行模式四…

[Vue的数据绑定]一.Vue的数据绑定;二.Vue的事件绑定;三.Class和Style的绑定;四.Vue的过滤器;五.Vue脚手架的使用

目录 一.Vue的数据绑定 1.单向数据绑定&#xff1a;将Model绑定到View上&#xff0c;当通过JavaScript代码改变了Model时&#xff0c;View就会自动刷新。不需要进行额外的DOM操作就可以实现视图和模型的联动 &#xff08;1&#xff09;插值表达式&#xff1a;{{ 表达式 }}&am…

pandas 使用

import pandas as pd a [3,7,2] myvar pd.Series(a,index["x","y","z"]) print(myvar["x"]) #结果是3 #给序列赋值index &#xff0c;然后可以根据index找到对应的数 data {"col1": range(-5,0), "col2": r…

半入耳式耳机适合跑步吗、最适合跑步的五款耳机分享

好的跑步耳机可以帮助您跑得更努力、更快和更久。研究发现&#xff0c;听音乐可以提高跑步成绩&#xff0c;尤其是在速度方面。同时&#xff0c;随着音乐锻炼可以提高跑步者的速度并减少精神疲劳&#xff0c;帮助您自信地打破这些束缚。那么目前市面上有哪些无线耳机是适合跑步…

【算法】分治算法(第三章习题解答)

3 分治算法 3.1 设 AAA 是 nnn 个非 000 实数构成的数组, 设计一个算法重新排列数组中的数, 使得负数都排在正数前面. 要求算法使用 O(n)O(n)O(n) 的时间和 O(1)O(1)O(1) 的空间. 算法设计&#xff1a;由于算法要求使用 O(n)O(n)O(n) 的时间和 O(1)O(1)O(1) 的空间&#xff0…

力扣sql入门篇(八)

力扣sql入门篇(八) 1 订单最多的客户 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 SELECT customer_number FROM Orders GROUP BY customer_number having count(order_number)(SELECT max(o1.number)FROM (SELECT count(order_number) numberFRO…

电压放大器在超声导波声弹特性的液压管路压力检测中的应用

实验名称&#xff1a;电压放大器在超声导波声弹特性的液压管路压力检测中的应用 研究方向&#xff1a;超声检测 实验目的&#xff1a; 为实现农机装备液压系统的非介入式压力检测&#xff0c;在分析适合压力检测的超声导波声弹敏感模态与激励频率的基础上&#xff0c;搭建了一套…

用埃式筛法来求解素数。————C++

目录埃式筛法埃式筛法求解某一个数字包含的所有素数数组Code运行结果埃式筛法判断某一个数字是否为素数Code运行结果埃式筛法 首先要了解什么式埃式筛法之前&#xff0c;需要知道一个定理。 就是素数的整数倍一定不是素数。 了解了这个就基本大概懂了埃式筛法。 首先初始化…

C语言线性表实现:顺序表

文章目录&#xff1a;概念理解&#xff1a;1. 动态顺序表结构体&#xff1a;2. 顺序表动态初始化&#xff1a;3. 顺序表扩容&#xff1a;4. 插入&#xff1a;5. 删除&#xff1a;6. 按位序查找&#xff1a;7. 按值查找&#xff1a;8. 输出顺序表&#xff1a;9. 判断顺序表是否相…

UniSCA漏洞优先级排序

当谈到开源漏洞时&#xff0c;我们会发现它们似乎永远处于增长状态。事实上&#xff0c;UniSCA的开源风险报告显示&#xff0c;与2021年同期相比&#xff0c;2022年前9个月添加到UniSCA漏洞数据库中的开源软件漏洞数量增长了33% 。然而&#xff0c;虽然有些漏洞会带来严重的业务…