【Python笔记-设计模式】备忘录模式

一、说明

备忘录模式是一种行为设计模式,允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。

(一) 解决问题

主要解决在不破坏封装性的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态,以便在需要时恢复对象到之前的状态。

(二) 使用场景

  • 撤销操作、历史记录、快照等
  • 需要保持对象的封装性,不希望暴露其内部状态的细节给外部时

二、结构

  1. 原发器(Originator)类可以生成自身状态的快照,也可以在需要时通过快照恢复自身状态。
  2. 备忘录(Memento)是原发器状态快照的值对象(valueobject)。通常做法是将备忘录设为不可变的,并通过构造函数一次性传递数据。
  3. 负责人(Caretaker)仅知道“何时”和“为何”捕捉原发器的状态,以及何时恢复状态。负责人通过保存备忘录栈来记录原发器的历史状态。当原发器需要回溯历史状态时,负责人将从栈中获取最顶部的备忘录,并将其传递给原发器的恢复(restoration)方法。
  4. 在该实现方法中,备忘录类将被嵌套在原发器中。这样原发器就可访问备忘录的成员变量和方法,即使这些方法被声明为私有。另一方面,负责人对于备忘录的成员变量和方法的访问权限非常有限:它们只能在栈中保存备忘录,而不能修改其状态。

三、伪代码

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__doc__ = """
备忘录模式

例:假设有一个文本编辑器应用程序,用户可以在其中编辑文本,并且可以撤销和恢复操作
"""


class Memento:
    """备忘录(Memento)"""

    def __init__(self, content):
        self._content = content

    def get_content(self):
        return self._content


class Originator:
    """原发器(Originator)"""

    def __init__(self):
        self._content = ""

    def type(self, text):
        self._content += text

    def get_content(self):
        return self._content

    def create_memento(self):
        return Memento(self._content)

    def restore_from_memento(self, memento):
        self._content = memento.get_content()


class Caretaker:
    """负责人(Caretaker)"""

    def __init__(self):
        self._mementos = []

    def add_memento(self, memento):
        print(f"当前内容: {memento.get_content()}")
        self._mementos.append(memento)

    def get_memento(self, index):
        print("撤销到指定步骤")
        return self._mementos[index]


if __name__ == "__main__":
    """
        当前内容: Hello, 
        当前内容: Hello, world!
        撤销到指定步骤
        当前内容: Hello, 
    """
    originator = Originator()
    caretaker = Caretaker()

    # 用户开始编辑文本
    originator.type("Hello, ")
    memento1 = originator.create_memento()
    caretaker.add_memento(memento1)

    # 用户继续编辑文本
    originator.type("world!")
    memento2 = originator.create_memento()
    caretaker.add_memento(memento2)

    # 用户撤销操作
    memento = caretaker.get_memento(0)
    originator.restore_from_memento(memento)

    print(f"当前内容: {memento.get_content()}")

四、优缺点

优点

  • 封装性好:备忘录模式可以有效地封装对象的状态,不暴露其内部细节,符合面向对象设计的封装原则。
  • 简化原始对象:备忘录模式可以将对象的状态保存在备忘录对象中,从而简化了原始对象的结构,使其更加清晰和易于维护。

缺点

  • 性能影响:频繁保存和恢复对象状态可能会影响程序的性能,特别是在状态较大或者对象较复杂的情况下。
  • 实现复杂度高:备忘录模式的实现可能较为复杂,特别是涉及到多个对象状态的保存和恢复时。

【Python笔记】设计模式-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Restful风格解释

示例对比 传统风格开发 Restful风格开发 结论: 传统风格开发中,前端不同操作使用不同的url来访问后端,使得访问变得麻烦restful风格中,前端使用相同的url来访问后端,但是用数据传送方式进行区分(get为请求…

鸿蒙OS应用编程实战:构建未来应用的基石

💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 引言 鸿蒙OS(HarmonyOS&#xff0…

vue3 构建项目

一.使用vite构建: npm init vitelatest 项目名称 构建的项目模板 进入项目 cd 项目名称 安装项目依赖包 npm install 启动项目 npm run dev 二.使用vue脚手架构建: npm init vuelatest 后续基本差不多

Docker本地部署GPT聊天机器人并实现公网远程访问

文章目录 前言1. 拉取相关的Docker镜像2. 运行Ollama 镜像3. 运行Chatbot Ollama镜像4. 本地访问5. 群晖安装Cpolar6. 配置公网地址7. 公网访问8. 固定公网地址9. 结语 前言 随着ChatGPT 和open Sora 的热度剧增,大语言模型时代,开启了AI新篇章,大语言模型的应用非常广泛&…

练习 1 Web EasySQL极客大挑战

CTF Week 1 EasySQL极客大挑战 BUUCTF 典中典复习 Web SQL 先尝试输入,找一找交互页面 check.php 尝试万能语句 a’ or true SQL注入:#和–的作用 get传参只能是url编码,注意修改编码,输入的字符串要改成url格式。 POST请求和…

机器视觉——硬件选型

1、相机选型 在选择机器视觉相机时,通常需要考虑以下几个方面: 1、分辨率:相机的分辨率决定了其拍摄图像的清晰度和细节程度。根据具体的应用需求,可以选择适当的分辨率范围。 2、帧率:帧率表示相机每秒钟能够拍摄的…

文献速递:帕金森的疾病分享--使用机器学习方法挖掘影像和临床数据以诊断和早期检测帕金森病

文献速递:帕金森的疾病分享–使用机器学习方法挖掘影像和临床数据以诊断和早期检测帕金森病 Title 题目 Mining imaging and clinical data with machine learning approaches for the diagnosis and early detection of Parkinson’s disease 使用机器学习方法…

Redisson限流算法

引入依赖 <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.12.3</version> </dependency>建议版本使用3.15.5以上 使用 这边写了一个demo示例&#xff0c;定…

Html零基础入门教程(非常详细)

文章目录 1.认识HTML2.html 框架3.HTML常见标签4.HTML语法特征5.列表 1.认识HTML html是超文本标记语言: 目前最新版本是html5,由w3c(万维网联盟)完成标准制定。 声明文档的类型是html5 超文本标记语言。 HTML &#xff0c;全称“Hyper Text Markup Language&#xff08;超文…

Python是垃圾?千万不要再学Python了?

“人生苦短&#xff0c;快学Python”这句话&#xff0c;相信大家都有看到过&#xff0c;但是有细心留意过&#xff0c;就会发现Python其实在网上的评价褒贬不一&#xff0c;有好评&#xff0c;也有差评。这就会给那些不懂Python却想要学Python的一些人造成困惑&#xff0c;我到…

mongo之常用数据库操作

目录 一、准备环境 二、日常记录及执行示范 连接数据库查询版本查询表总数模糊查询(使用正则)查询文档中数据条数排序大于等于查询有哪些库时间查询不在条件内的查询复制数据更新字段名称删除数据库 四、高阶查询 五、备份迁移数据库 总结 一、准备环境 借鉴&#xff1a;…

【算法分析与设计】最大二叉树

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;算法分析与设计 ⛺️稳中求进&#xff0c;晒太阳 题目 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最…

Logic Pro:专业音乐制作软件,为你的音乐插上翅膀

Logic Pro是一款功能强大的音乐制作软件&#xff0c;专为专业音乐人和音乐爱好者设计。它提供了全面的音乐创作工具&#xff0c;包括音频录音、编辑、混音、合成以及自动化等功能&#xff0c;让你能够轻松实现音乐梦想。 Logic Pro软件获取 首先&#xff0c;Logic Pro拥有卓越…

关于网站的保姆级攻略

什么是域名&#xff1f; 域名是互联网上用于识别和定位计算机和网络服务的字符串。它提供了一个便于人们记忆和使用的名称&#xff0c;用来代替复杂的IP地址&#xff0c;可用于从客户端浏览器&#xff08;Chrome、EDGE&#xff09;访问网站。简单来说&#xff0c;域名是用户在浏…

这一次,彻底解决滚动穿透

什么是滚动穿透 如图所示&#xff0c;有一层遮罩蒙层覆盖在body上时&#xff0c;当我们滚动遮罩层&#xff0c;它下面的内容也会跟着一起滚动&#xff0c;看起来好像是上面的滚动事件穿透到下面的DOM元素上一样&#xff0c;我们称之为滚动穿透。 阻止冒泡&#xff1f; 刚开始…

Window系统禅道BUG管理系统安装配置并实现公网远程访问

文章目录 前言1. 本地安装配置BUG管理系统2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射本地服务3. 测试公网远程访问4. 配置固定二级子域名4.1 保留一个二级子域名5.1 配置二级子域名6. 使用固定二级子域名远程 前言 BUG管理软件,作为软件测试工程师的必备工具之一。在…

【Linux】进程信号 --- 信号的产生 保存 捕捉递达

文章目录 信号的感知信号的结构描述 一、信号的产生1.通过键盘发送信号2.通过系统调用发送信号 二、信号的保存&#xff08;PCB内部的两张位图和一个函数指针数组&#xff09;理解三张数据结构表block pending haldler 三、通过代码编写 理解 信号的保存和递达1.信号集操作的库…

看到递归就晕?带你理解递归的本质!【基础算法精讲 09】

104 . 二叉树的最大深度 链接 : . - 力扣&#xff08;LeetCode&#xff09; 思路 : 对于题意&#xff0c;可以拆分为 : ans max(左子树的最大深度 &#xff0c; 右子树的最大深度) 1 ; 原问题 : 计算整颗树的最大深度 &#xff1b; 子问题 : 计算左右子树的最大深度 ;…

Postgresql中dblink扩展的使用

一、介绍 Postgresql数据库提供了一个dblink扩展的插件&#xff0c;能够直接在一个数据库中操作另外一个远程数据库&#xff0c;比如&#xff1a;一个数据库在服务器A上&#xff0c;另外一个数据库在服务器B上&#xff0c;我可以在A这台服务器数据库上面建立一个到B服务器数据库…

Redis是单线程还是多线程?

说Redis是单线程或者是多线程这种说法并不严谨&#xff0c;要拿版本说话&#xff0c;Redis的版本有很多3.x、4.x和6.x&#xff0c;版本不同架构也是不同的&#xff0c;不限定版本问是否单线程是不太严谨的。 版本3.x&#xff0c;最早版本&#xff0c;此时Redis是单线程的版本4…