Python 如何实现备忘录设计模式?什么是备忘录设计模式?Python 备忘录设计模式示例代码

什么是备忘录(Memento)设计模式?

备忘录(Memento)设计模式是一种行为型设计模式,用于捕获一个对象的内部状态,并在对象之外保存这个状态,以便在需要时恢复对象到先前的状态。这种模式允许将对象状态的保存和恢复功能封装在备忘录对象中,同时不破坏对象的封装性。

在这里插入图片描述

主要角色

  1. 发起人(Originator): 这个角色创建一个包含其当前状态的备忘录,并可以使用备忘录恢复其状态。发起人可以在备忘录中存储和恢复状态。

  2. 备忘录(Memento): 这个角色存储了发起人的内部状态。备忘录对象可以包含发起人的状态快照,但不会暴露给其他对象。

  3. 管理者(Caretaker): 这个角色负责保存备忘录。它可能会保存多个备忘录,但不对备忘录的内容进行操作。

工作流程

  1. 发起人创建备忘录: 当发起人需要保存其状态时,创建一个备忘录,并将其内部状态保存到备忘录中。

  2. 发起人恢复状态: 如果需要恢复到之前的状态,发起人可以使用备忘录中保存的状态信息进行恢复。

优点:

  1. 封装性良好: 备忘录模式允许将对象状态的保存和恢复功能封装在备忘录对象中,不暴露给其他对象,从而保持了对象状态的封装性。

  2. 历史记录管理: 允许在不破坏对象封装性的情况下,保存对象状态的历史记录,方便实现撤销、恢复、回滚等功能。

  3. 支持撤销和恢复: 备忘录模式能够保存对象不同时间点的状态,支持对对象状态的撤销操作,使得系统更具有交互性和灵活性。

缺点:

  1. 资源消耗: 如果对象状态非常庞大或者备忘录对象的管理复杂,可能会消耗大量内存和计算资源,对系统性能产生影响。

  2. 状态管理复杂性: 当需要管理大量状态或者状态之间存在复杂的依赖关系时,备忘录模式可能会增加系统的复杂性和维护成本。

  3. 备忘录对象的访问限制: 在某些情况下,备忘录对象的状态可能需要在发起人之外的对象中使用,但备忘录模式通常会限制了状态的访问性。

总的来说,备忘录模式可以有效地保存对象状态,支持撤销和恢复操作,但在状态管理复杂、资源消耗和访问限制方面可能存在一些缺点。因此,在使用备忘录模式时需要权衡其优缺点,并根据实际情况进行合理的选择和应用。


Python 备忘录设计模式示例代码(一):

以下是备忘录模式的简单示例:

# 备忘录类
class Memento:
    def __init__(self, state):
        self._state = state

    def get_state(self):
        return self._state

# 发起人类
class Originator:
    def __init__(self):
        self._state = None

    def set_state(self, state):
        self._state = state

    def save_to_memento(self):
        return Memento(self._state)

    def restore_from_memento(self, memento):
        self._state = memento.get_state()

# 管理者类
class Caretaker:
    def __init__(self):
        self._memento = None

    def get_memento(self):
        return self._memento

    def set_memento(self, memento):
        self._memento = memento

# 客户端代码
if __name__ == "__main__":
    originator = Originator()
    caretaker = Caretaker()

    # 设置状态并保存到备忘录
    originator.set_state("State #1")
    caretaker.set_memento(originator.save_to_memento())

    # 修改状态
    originator.set_state("State #2")

    # 恢复状态
    originator.restore_from_memento(caretaker.get_memento())

这个示例展示了如何使用备忘录模式保存和恢复发起人对象的状态。发起人可以创建备忘录并将其状态保存到备忘录中,在需要时可以恢复到先前保存的状态。


Python 备忘录设计模式示例代码(二):

假设我们有一个电子邮件编辑器,在用户编辑邮件时需要实现撤销(Undo)功能,可以使用备忘录模式来保存不同编辑状态,以便用户可以撤销到先前的状态。

# 备忘录类
class EmailMemento:
    def __init__(self, content):
        self._content = content

    def get_content(self):
        return self._content

# 发起人类
class EmailEditor:
    def __init__(self):
        self._content = ""

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

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

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

# 管理者类
class HistoryManager:
    def __init__(self):
        self._history = []

    def add_to_history(self, memento):
        self._history.append(memento)

    def get_last_memento(self):
        if self._history:
            return self._history.pop()

# 客户端代码
if __name__ == "__main__":
    editor = EmailEditor()
    history = HistoryManager()

    # 编辑邮件内容并保存状态
    editor.set_content("First draft of the email.")
    history.add_to_history(editor.create_memento())

    # 编辑邮件内容
    editor.set_content("Second draft with more details.")

    # 恢复到先前的状态
    last_memento = history.get_last_memento()
    if last_memento:
        editor.restore_from_memento(last_memento)
        print(f"Restored to previous draft: {editor._content}")
    else:
        print("No more history to restore.")

这个示例模拟了一个简单的电子邮件编辑器。用户可以编辑邮件内容,并使用备忘录模式保存不同版本的邮件状态。通过管理者类,用户可以撤销到先前保存的状态,恢复邮件内容到之前的版本。


使用备忘录设计模式时,需要注意哪些地方?

使用备忘录设计模式时需要注意以下几个方面:

  1. 状态的复杂性: 考虑对象状态的复杂性和大小。如果状态非常庞大或者包含敏感信息,可能会导致备忘录对象的创建和管理变得复杂。在这种情况下,需要权衡保存状态的合适性和开销。

  2. 备忘录的生命周期: 确保备忘录的生命周期符合需求。备忘录应该在合适的时间创建和使用,以及在不需要时进行销毁,避免占用过多的资源。

  3. 封装性和隐私性: 保持备忘录的封装性和隐私性。确保备忘录对象的状态只有发起人可以访问和修改,其他对象不能直接操作备忘录对象的状态。

  4. 管理者的责任: 管理者(Caretaker)对于维护备忘录的历史记录和状态的正确恢复至关重要。管理者应该准确地管理备忘录的存储和恢复过程。

  5. 备忘录的可变性: 在某些情况下,备忘录对象的状态可能会发生变化。考虑到备忘录对象可能需要支持状态更新的情况,以便在恢复时能够正确地反映最新状态。

  6. 性能考虑: 对于大型状态或者频繁的状态保存操作,需要考虑备忘录模式对性能的影响,以及如何优化备忘录对象的创建和管理。

综上所述,使用备忘录模式时,需要关注状态的复杂性和大小、备忘录对象的封装性、生命周期管理以及对历史记录的正确恢复等方面,以确保备忘录模式的正确实现和使用。


本文就到这里了,感谢您的阅读 。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇

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

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

相关文章

腾讯云服务器带宽计费模式_按流量和带宽收费说明

腾讯云服务器带宽计费模式分为“按带宽计费”和“按使用流量”两种计费模式:按带宽计费是预付费,一次性购买固定带宽值,先付费;按使用流量计费是先使用后付费,根据云服务器公网出方向实际产生流量来计算。如何选择带宽…

java--拼图游戏

1、了解拼图游戏基本功能: 拼图游戏内容由若干小图像块组成的,通过鼠标点击图像块上下左右移动,完成图像的拼凑。 2、拼图游戏交互界面设计与开发: 通过创建窗体类、菜单、中间面板和左右面板完成设计拼图的交互界面 &#xff…

突发 Chatgpt之父被开,GPT放开注册,注册难度大幅降低!

大家好,我是菜鸟哥,又到周末啦,我们聊一下非技术的话题。科技圈chatgpt属于当红辣子鸡,是目前最火的话题。前不久才开的发布会,然后没几天被黑客攻击,导致服务中断,然后openai 又突然宣布gpt4停…

斯坦福机器学习 Lecture2 (假设函数、参数、样本等等术语,还有批量梯度下降法、随机梯度下降法 SGD 以及它们的相关推导,还有正态方程)

假设函数定义 假设函数,猜一个 x->y 的类型,比如 y ax b,随后监督学习的任务就是找到误差最低的 a 和 b 参数 有时候我们可以定义 x0 1,来让假设函数的整个表达式一致统一 如上图是机器学习中的一些术语 额外的符号&#xf…

解决向日葵远程控制linux命令行版本无法输入密码的问题

就是如下所示的框,官方说是按方向键↓选择用户名和密码的输入框输入,但是按方向键死活没用,研究了之后按tab键就行了。

hyperledger fabric2.4测试网络添加组织数量

!!!修改内容比较繁琐,预期未来提供模板修改 修改初始配置文件,初始添加3个组织 organizations文件夹 /cryptogen文件夹下创建文件crypto-config-org3.yaml,内容如下: PeerOrgs:# ---------------------------------------------------------------------------# Org3# ----…

聊聊近些年 CPU 在微架构、IO 速率上的演进过程

大家好,我是飞哥! 在上一篇《深入了解 CPU 的型号、代际架构与微架构》 中我们介绍了我手头的一颗 Intel(R) Core(TM) i5 的型号规则,以及它的物理硬件的 Die 图结构。以及它对应的 Skylake 核的微架构实现。 不少同学开始问我其它型号的 CPU…

文本转语音

免费工具 音视频转译 通义听悟 | https://tingwu.aliyun.com/u/wg57n33kml5nkr3p 音色迁移 speechify | https://speechify.com/voice-cloning/ 视频生成 lalamu | http://lalamu.studio/demo/ 画质增强 topazlabs video AI | https://www.topazlabs.com 付费工具 rask | htt…

动态规划解背包问题

题目 题解 def knapsac(W: int, N: int, wt: List[int], val: List[int]) -> int:# 定义状态动作价值函数: dp[i][j],对于前i个物品,当前背包容量为j,最大的可装载价值dp [[0 for j in range(W1)] for i in range(N1)]# 状态动作转移for…

基于适应度相关算法优化概率神经网络PNN的分类预测 - 附代码

基于适应度相关算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于适应度相关算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于适应度相关优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要:针…

MySQL 教程 1.2

上期教程网友笔记整理 MySQL 重置密码 如果你忘记 MySQL 密码,可以通过修改 my.cnf 文件添加 skip-grant-tables 来重置密码,步骤如下: 1、打开 my.cnf 配置文件,找到 [mysqld] ,然后在该行下面添加以下参数&#x…

vue2中的插槽

vue2中的插槽 props[数学公式]属性: 各种数据类型值。子组件接收到之后做不同的判断实现不同的效果来实现复用性。 插槽:HTML dom元素。 预留属性、预留插槽。 调用语法:单闭合/双闭合。需要传插槽,就用双闭合;不需要就单双都可以…

Linux - 进一步理解 文件系统 - inode - 机械硬盘

详谈机械磁盘 在上一篇博客当中,已经对 用户级缓冲区 和 系统缓冲区 的区别,和 初步认识 C 库函数 封装的 文件接口这些做了阐述。具体可以参考下述博客: Linux - 用户级缓冲区和系统缓冲区 - 初步理解Linux当中文件系统-CSDN博客 本博客将…

【算法挨揍日记】day21——64. 最小路径和、174. 地下城游戏

64. 最小路径和 64. 最小路径和 题目描述: 给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 说明:每次只能向下或者向右移动一步。 解题思路: 状态表示&…

量化交易:建立趋势跟踪策略的五个指标

什么是趋势跟踪策略? 趋势跟踪策略是只需需顺势而为的策略,即在价格上涨时买入,在价格开始下跌时卖出。在趋势跟踪策略中,人们的目标不是预测或预测,而只是关注市场上的任何新兴趋势。 趋势是如何出现的?…

毅速丨3D打印透气钢正在被各行业广泛应用

随着制造技术的发展,企业对生产效率和产品品质的进一步提高,3D打印透气钢已逐渐在各行业中广泛应用。传统的透气钢制造方法,如粉末冶金和扩散焊,通常只能加工出透气钢的嵌块,使用时需要进行镶嵌,存在强度不…

十八、Linux任务调度crond和at

1、crond任务调度 crond进行 定时任务的设置 概述 任务调度:是指系统在某个时间执行的特定的命令或程序。 任务调度分类:1.系统工作:有些重要的工作必须周而复始地执行。如病毒扫描等 个别用户工作:个别用户可希望执行某些程序…

Kotlin学习(一)

Kotlin学习&#xff08;一&#xff09; 1.使用IDEA构建Kotlin项目 新建工程即可 我这里选择的Build System是IntelliJ&#xff0c;虽然我没用过但是这是Kotlin基础学习应该不会用到其他依赖 2.Hello World package com.simonfun main(args:Array<String>){println(&q…

list,dict使用方法

list, dict的使用 list的使用&#xff1a; ori_list [1, 2, 3] append: 使用append为列表增加1个元素4 输出增加元素之后的列表 ori_list [1, 2, 3] ori_list.append(4) print(ori_list)extend: 给定列表[8, 7, 6],将ori_list和给定的列表进行合并 输出合并后的列表 ori_l…

统信UOS通过源码安装软件提示“configure: error: cannot run C compiled programs.”错误

1. 问题说明 使用源码的方式安装git软件&#xff0c;安装过程中出现两个错误。 编译错误“cannot run C compiled programs” XC:~/Downloads/git-2.42.1$ ./configure --prefix/home/software/git-2.42.1 configure: Setting lib to lib (the default) configure: Will try…