设计模式:备忘录模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

news2024/11/18 1:32:40

上一篇《中介者模式》                                                              下一篇《状态模式》

简介:

备忘录模式,它是一种软件设计模式,它允许在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

备忘录模式的使用场景:
1、需要保存和恢复对象的状态,但不希望通过暴露对象内部细节来实现。例如,在游戏存档、一些编辑工具中的“撤销”操作,或者浏览器中的后退功能中,用户希望保存和恢复对象的状态,但并不需要访问或修改对象的内部状态。
2、需要实现撤销操作。例如,在Word中编写文档,如果想要撤销之前的输入/删除操作,可以使用Ctrl+Z执行“撤销”操作。在这种情况下,备忘录模式可以保存文档的某个状态,以便用户在需要时恢复到该状态。
3、需要实现状态恢复。例如,在游戏中,玩家可能需要保存游戏的状态,以便在需要时恢复到之前的状态。备忘录模式可以保存游戏的状态,并在需要时恢复该状态。

总之,备忘录模式适用于需要保存和恢复对象状态的情况,包括但不限于以上场景。需要注意的是,使用备忘录模式需要消耗一定的内存资源,因此在使用时需要考虑内存消耗的问题。

备忘录模式的创建步骤:
1、创建发起人(Originator)类,该类中定义了创建备忘录(Memento)的接口,用于创建、使用和释放备忘录。
2、创建备忘录(Memento)类,该类中定义了需要保存的数据,并且这些数据必须是不可变的。
3、创建管理者(Caretaker)类,该类中保存备忘录(Memento),并且不应该对备忘录的内容进行操作或检查。
4、在发起人(Originator)类中定义一个恢复状态的方法,该方法用于从备忘录(Memento)中恢复对象的状态。
5、在发起人(Originator)类中定义一个创建备忘录(Memento)的方法,该方法用于创建一个新的备忘录(Memento),并将当前对象的状态保存到备忘录中。
6、在发起人(Originator)类中使用备忘录(Memento)的方法,该方法用于使用备忘录(Memento)来恢复对象的状态。
7、在发起人(Originator)类中定义一个释放备忘录(Memento)的方法,该方法用于释放备忘录(Memento),以便管理者(Caretaker)可以保存或使用它。
8、在管理者(Caretaker)类中定义一个保存备忘录(Memento)的方法,该方法用于保存发起人(Originator)创建的备忘录(Memento)。
9、在管理者(Caretaker)类中定义一个恢复备忘录(Memento)的方法,该方法用于恢复发起人(Originator)对象的状态。

以上是备忘录模式的基本创建步骤,在使用时可以根据需要进行适当的修改和扩展。

备忘录模式的优点,主要包括:
1、保存对象状态:备忘录模式可以保存对象的状态,以便在需要时恢复该状态。这对于需要撤销操作或者恢复历史状态的应用场景非常有用。
2、封装性:备忘录模式实现了内部状态的封装,只有创建备忘录的发起人才能访问备忘录中的状态信息,其他对象无法访问,增强了数据的安全性。
3、简化发起人:备忘录模式简化了发起人,发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。

备忘录模式的缺点,主要包括:
1、资源消耗过大:如果需要保存的原发器类的成员变量太多,就不可避免需要占用大量的存储空间,每保存一次对象的状态都需要消耗一定的系统资源。
2、实现复杂度较高:备忘录模式需要实现发起人、备忘录、管理者等多个角色,并且需要维护备忘录的创建、存储、恢复等操作,因此实现起来相对比较复杂。
3、可能引入数据不一致的问题:由于备忘录模式需要保存和恢复对象的状态,如果在使用过程中出现异常或者并发操作,就可能导致数据不一致的问题。
4、可能引入性能问题:由于备忘录模式需要保存和恢复对象的状态,如果频繁地使用备忘录模式,可能会对系统的性能造成一定的影响。

因此,在使用备忘录模式时需要注意权衡利弊,根据实际需求和资源消耗来决定是否使用。同时,也需要在实现过程中注意保证数据的完整性和一致性,避免出现异常或并发操作对数据造成影响。


示例:

一、C#备忘录模式

以下是一个示例,展示了如何在C#中实现备忘录模式:

using System;  
  
// 发起人类  
public class Originator  
{  
    private string state;  
  
    public void SetState(string state)  
    {  
        this.state = state;  
    }  
  
    public Memento CreateMemento()  
    {  
        return new Memento(this.state);  
    }  
  
    public void RestoreFromMemento(Memento memento)  
    {  
        this.state = memento.State;  
    }  
}  
  
// 备忘录类  
public class Memento  
{  
    private string state;  
  
    public Memento(string state)  
    {  
        this.state = state;  
    }  
  
    public string State  
    {  
        get { return this.state; }  
    }  
}  
  
// 管理者类  
public class Caretaker  
{  
    private Memento memento;  
  
    public void SetMemento(Memento memento)  
    {  
        this.memento = memento;  
    }  
  
    public Memento GetMemento()  
    {  
        return this.memento;  
    }  
}  
  
// 客户端代码  
public class Client  
{  
    static void Main(string[] args)  
    {  
        Originator originator = new Originator();  
        originator.SetState("原始状态"); // 设置原始状态  
        Memento memento = originator.CreateMemento(); // 创建备忘录  
        originator.SetState("修改后的状态"); // 修改状态  
        Caretaker caretaker = new Caretaker(); // 创建管理者对象  
        caretaker.SetMemento(memento); // 将备忘录交给管理者保存  
        Console.WriteLine("当前状态:" + originator.State); // 输出当前状态(修改后的状态)  
        originator.RestoreFromMemento(caretaker.GetMemento()); // 从管理者中恢复到之前的状态(原始状态)  
        Console.WriteLine("恢复后的状态:" + originator.State); // 输出恢复后的状态(原始状态)  
    }  
}

二、java备忘录模式

备忘录模式通常通过以下方式实现:

import java.util.ArrayList;  
import java.util.List;  
  
// 发起人类  
public class Originator {  
    private List<String> states = new ArrayList<>();  
  
    public void setState(String state) {  
        states.add(state);  
    }  
  
    public Memento createMemento() {  
        return new Memento(states);  
    }  
  
    public void restoreFromMemento(Memento memento) {  
        states = memento.getStates();  
    }  
}  
  
// 备忘录类  
public class Memento {  
    private List<String> states;  
  
    public Memento(List<String> states) {  
        this.states = states;  
    }  
  
    public List<String> getStates() {  
        return states;  
    }  
}  
  
// 管理者类  
public class Caretaker {  
    private Memento memento;  
  
    public void setMemento(Memento memento) {  
        this.memento = memento;  
    }  
  
    public Memento getMemento() {  
        return memento;  
    }  
}  
  
// 客户端代码  
public class Client {  
    public static void main(String[] args) {  
        Originator originator = new Originator();  
        originator.setState("原始状态"); // 设置原始状态  
        Memento memento = originator.createMemento(); // 创建备忘录  
        originator.setState("修改后的状态"); // 修改状态  
        Caretaker caretaker = new Caretaker(); // 创建管理者对象  
        caretaker.setMemento(memento); // 将备忘录交给管理者保存  
        System.out.println("当前状态:" + originator.getState()); // 输出当前状态(修改后的状态)  
        originator.restoreFromMemento(caretaker.getMemento()); // 从管理者中恢复到之前的状态(原始状态)  
        System.out.println("恢复后的状态:" + originator.getState()); // 输出恢复后的状态(原始状态)  
    }  
}

三、javascript备忘录模式

在JavaScript中,备忘录实现方式如下:

// 发起人类  
class Originator {  
  constructor() {  
    this.states = [];  
  }  
  
  setState(state) {  
    this.states.push(state);  
  }  
  
  createMemento() {  
    return { states: this.states.slice() };  
  }  
  
  restoreFromMemento(memento) {  
    this.states = memento.states;  
  }  
}  
  
// 备忘录类  
class Memento {  
  constructor(states) {  
    this.states = states;  
  }  
  
  getStates() {  
    return this.states;  
  }  
}  
  
// 管理者类  
class Caretaker {  
  constructor() {  
    this.memento = null;  
  }  
  
  setMemento(memento) {  
    this.memento = memento;  
  }  
  
  getMemento() {  
    return this.memento;  
  }  
}  
  
// 客户端代码  
const originator = new Originator();  
originator.setState('原始状态'); // 设置原始状态  
const memento = originator.createMemento(); // 创建备忘录  
originator.setState('修改后的状态'); // 修改状态  
const caretaker = new Caretaker(); // 创建管理者对象  
caretaker.setMemento(memento); // 将备忘录交给管理者保存  
console.log('当前状态:', originator.states); // 输出当前状态(修改后的状态)  
originator.restoreFromMemento(caretaker.getMemento()); // 从管理者中恢复到之前的状态(原始状态)  
console.log('恢复后的状态:', originator.states); // 输出恢复后的状态(原始状态)

四、C++备忘录模式

以下是在C++中实现备忘录模式:

#include <iostream>  
#include <string>  
#include <vector>  
  
// 发起人类  
class Originator {  
public:  
  std::vector<std::string> states;  
  
  void setState(const std::string& state) {  
    states.push_back(state);  
  }  
  
  Memento* createMemento() {  
    return new Memento(states);  
  }  
  
  void restoreFromMemento(Memento* memento) {  
    states = memento->states;  
  }  
};  
  
// 备忘录类  
class Memento {  
public:  
  std::vector<std::string> states;  
  
  Memento(const std::vector<std::string>& states) : states(states) {}  
};  
  
// 管理者类  
class Caretaker {  
public:  
  Memento* memento;  
  
  Caretaker() : memento(nullptr) {}  
  
  void setMemento(Memento* memento) {  
    this->memento = memento;  
  }  
  
  Memento* getMemento() {  
    return memento;  
  }  
};  
  
// 客户端代码  
int main() {  
  Originator originator;  
  originator.setState("原始状态"); // 设置原始状态  
  Memento* memento = originator.createMemento(); // 创建备忘录  
  originator.setState("修改后的状态"); // 修改状态  
  Caretaker caretaker; // 创建管理者对象  
  caretaker.setMemento(memento); // 将备忘录交给管理者保存  
  std::cout << "当前状态:" << originator.states.back() << std::endl; // 输出当前状态(修改后的状态)  
  originator.restoreFromMemento(caretaker.getMemento()); // 从管理者中恢复到之前的状态(原始状态)  
  std::cout << "恢复后的状态:" << originator.states.back() << std::endl; // 输出恢复后的状态(原始状态)  
  return 0;  
}

五、python备忘录模式

以下是在python中实现备忘录模式:

from abc import ABC, abstractmethod  
  
class Memento(ABC):  
    @abstractmethod  
    def get_states(self):  
        pass  
  
class Originator:  
    def __init__(self):  
        self.states = []  
      
    def set_state(self, state):  
        self.states.append(state)  
      
    def create_memento(self):  
        return Memento(self.states[:])  
      
    def restore_from_memento(self, memento):  
        self.states = memento.get_states()  
  
class Caretaker:  
    def __init__(self):  
        self.memento = None  
      
    def set_memento(self, memento):  
        self.memento = memento  
      
    def get_memento(self):  
        return self.memento  
  
# 客户端代码  
if __name__ == '__main__':  
    originator = Originator()  
    originator.set_state('原始状态')  # 设置原始状态  
    memento = originator.create_memento()  # 创建备忘录  
    originator.set_state('修改后的状态')  # 修改状态  
    caretaker = Caretaker()  # 创建管理者对象  
    caretaker.set_memento(memento)  # 将备忘录交给管理者保存  
    print('当前状态:', originator.states[-1])  # 输出当前状态(修改后的状态)  
    originator.restore_from_memento(caretaker.get_memento())  # 从管理者中恢复到之前的状态(原始状态)  
    print('恢复后的状态:', originator.states[-1])  # 输出恢复后的状态(原始状态)

六、go备忘录模式

以下是一个示例,展示了如何在go中实现备忘录模式:

package main  
  
import (  
 "fmt"  
)  
  
// Originator 定义了创建备忘录和恢复备忘录的接口  
type Originator struct {  
 text string  
}  
  
func (o *Originator) SetText(text string) {  
 o.text = text  
}  
  
func (o *Originator) CreateMemento() *Memento {  
 return &Memento{text: o.text}  
}  
  
func (o *Originator) RestoreFromMemento(m *Memento) {  
 o.text = m.GetText()  
}  
  
// Memento 用于保存 Originator 的状态  
type Memento struct {  
 text string  
}  
  
func (m *Memento) GetText() string {  
 return m.text  
}  
  
// Caretaker 用于保存和恢复备忘录  
type Caretaker struct {  
 memento *Memento  
}  
  
func (c *Caretaker) SetMemento(m *Memento) {  
 c.memento = m  
}  
  
func (c *Caretaker) GetMemento() *Memento {  
 return c.memento  
}  
  
func main() {  
 originator := &Originator{}  
 originator.SetText("原始状态")  
   
 memento := originator.CreateMemento()  
 originator.SetText("修改后的状态")  
   
 fmt.Println("当前状态:", originator.text) // 输出当前状态(修改后的状态)  
   
 originator.RestoreFromMemento(memento) // 从备忘录中恢复到之前的状态(原始状态)  
 fmt.Println("恢复后的状态:", originator.text) // 输出恢复后的状态(原始状态)  
}

七、PHP备忘录模式

以下是一个示例,展示了如何在PHP中实现备忘录模式:

<?php  
  
// Originator 类定义了创建备忘录和恢复备忘录的接口  
class Originator {  
    private $state;  
  
    public function setState($state) {  
        $this->state = $state;  
    }  
  
    public function createMemento() {  
        return new Memento($this->state);  
    }  
  
    public function restoreFromMemento(Memento $memento) {  
        $this->setState($memento->getState());  
    }  
}  
  
// Memento 类用于保存 Originator 的状态  
class Memento {  
    private $state;  
  
    public function __construct($state) {  
        $this->state = $state;  
    }  
  
    public function getState() {  
        return $this->state;  
    }  
}  
  
// Caretaker 类用于保存和恢复备忘录  
class Caretaker {  
    private $memento;  
  
    public function setMemento(Memento $memento) {  
        $this->memento = $memento;  
    }  
  
    public function getMemento() {  
        return $this->memento;  
    }  
}  
  
// 客户端代码  
$originator = new Originator();  
$originator->setState("原始状态"); // 设置原始状态  
  
$memento = $originator->createMemento(); // 创建备忘录  
$originator->setState("修改后的状态"); // 修改状态  
  
echo "当前状态:" . $originator->getState() . "\n"; // 输出当前状态(修改后的状态)  
  
$originator->restoreFromMemento($memento); // 从备忘录中恢复到之前的状态(原始状态)  
echo "恢复后的状态:" . $originator->getState() . "\n"; // 输出恢复后的状态(原始状态)

《完结》


上一篇《中介者模式》                                                               下一篇《状态模式》

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

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

相关文章

基于springboot实现网吧管理系统项目【项目源码+论文说明】

基于springboot实现网吧管理系统演示 摘要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#x…

CH9329芯片应用—简介

概述 CH9329是一款串口转USB HID设备功能芯片&#xff0c;根据不同的工作模式&#xff0c;HID设备可以识别为&#xff1a;USB键盘设备、USB鼠标设备或者自定义HID类设备。接收串口数据&#xff0c;并自动根据串口工作模式进行数据解析&#xff0c;解析完成后按照HID类设备规范…

【漏洞复现】广联达 Linkworks办公OA SQL注入

广联达OA介绍 广联达办公OA是一款综合办公自动化解决方案&#xff0c;旨在提高组织内部的工作效率和协作能力。它提供了一系列功能和工具&#xff0c;帮助企业管理和处理日常办公任务、流程和文档。 资产收集 fofa&#xff1a;fid”/yV4r5PdARKT4jaqLjJYqw”或者body”/Servi…

Windows平台下将exe及其dll封包到新的exe

Windows平台下将exe及其dll封包到新的exe 〇、项目需求一、生成 exe二、通过 Dependencies 寻找所需dll三、将所需 dll 复制到 exe 同级目录下3.1 通过 python 脚本自动处理3.2 使用 Everthing 搜索特定dll3.3 验证 dll 是否完备 四、使用 Enigma Virtual Box 对 dll 和 exe 进…

ch3_6多线程举例

作者丨billom 来源丨投稿 编辑丨GiantPandaCV 云端深度学习的服务的性能加速通常需要算法和工程的协同加速&#xff0c;需要模型推理和计算节点的融合&#xff0c;并保证整个“木桶”没有太明显的短板。 如何在满足时延前提下让算法工程师的服务的吞吐尽可能高&#xff0c;尽…

Photoshop2024磨皮滤镜插件Portraiture

想要快速提升人像修图效果&#xff0c;让皮肤看起来更加光滑细腻吗&#xff1f;那么你可以尝试使用Photoshop磨皮滤镜插件。这些插件能够让你在短时间内快速有效地进行人像处理&#xff0c;无论是对于专业的设计师还是初学者来说都是非常实用的工具。 接下来&#xff0c;让我为…

AI时代中小企业算力需求爆发,惠普发布新品战99 Monster满血高算工作站

第17届DEMO CHINA创新中国峰会10月25日至26日在北京举行&#xff0c;吸引了国内众多优秀创新创业项目的积极参与。作为本届DEMO CHINA独家战略合作伙伴&#xff0c;惠普在大会上正式发布战家族新品战99 Monster满血高算工作站&#xff0c;满足AI时代中小企业对于算力的爆发式需…

Live800:客服中心质检管理的五大方法

客服中心质检管理是企业提供优质服务和客户满意度的关键。因此&#xff0c;企业必须采用适当的方法来管理客服质检以确保服务质量。本文将介绍客服中心质检管理的五大方法。 1、建立清晰的服务标准 建立清晰的服务标准是提高客服质量的关键因素。服务标准可以包括快速响应时间…

TypeScript详解

一、是什么 TypeScript 是 JavaScript 的类型的超集&#xff0c;支持ES6语法&#xff0c;支持面向对象编程的概念&#xff0c;如类、接口、继承、泛型等 超集&#xff0c;不得不说另外一个概念&#xff0c;子集&#xff0c;怎么理解这两个呢&#xff0c;举个例子&#xff0c;如…

广受欢迎的 VLC Media Player 开源媒体播放器软件已更新到 3.0.19 版

导读广受欢迎的 VLC Media Player 开源媒体播放器软件已更新到 3.0.19 版&#xff0c;这是继 VLC 3.0.18 发布近一年后的又一版本&#xff0c;其中包含大量改进和错误修复。 VLC 3.0.19 版本的亮点包括改进了软件解码对 AV1 HDR 的支持&#xff0c;支持 WAV 音频文件的 RIFF IN…

基于SSM的罪犯信息管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

数字化工厂:连接、集成与数据融合

随着科技的不断发展&#xff0c;数字化工厂管理系统逐渐成为制造业的重要趋势。数字化工厂的核心在于连接、集成与数据融合&#xff0c;通过这些技术手段&#xff0c;实现对设备、生产线、工厂、供应商、产品、客户等各个环节的全面优化&#xff0c;提升企业的生产效率和产品质…

字符串中的assert和strcat

assert&#xff1a;函数原型是&#xff1a;void assert( int expression );其作用是现计算表达式 expression &#xff0c;如果其值为假(即为0)&#xff0c;那么它先 stderr 打印一条出信息,然后通过调用 abort 来终止程序运行。使用assert 的缺点是&#xff0c;频繁的调用会影…

GoLong的学习之路(十二)语法之标准库 flag的使用

上回书说到&#xff0c;fmt的标准库的一些常用的使用函数。这次说flag的使用&#xff0c;以下这些库要去做了解。不然GG&#xff0c;Go语言内置的flag包实现了命令行参数的解析&#xff0c;flag包使得开发命令行工具更为简单。 文章目录 os.Argsflag包flag.Type()flag.TypeVar(…

AI口语APP的实现

AI口语应用程序是一种借助人工智能技术&#xff0c;旨在帮助用户提高口语能力、练习语言技能以及进行交流和学习语言的应用程序。这类应用通常提供以下主要功能&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交…

Ansys Speos | SPEOS 在HUD杂光分析中的应用

概述 随着汽车智能座舱的普及&#xff0c;HUD的装车率也随之增加&#xff0c;未来也可能会成为车内座舱的标配。而HUD是一个由光学&#xff0c;机械&#xff0c;电子&#xff0c;软件组成的复杂的高科技产品&#xff0c;其所在的汽车座舱是很复杂的环境。我们需要对HUD进行诸如…

2023年05月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 可以对Python代码进行多行注释的是&#xff1f;&#xff08; &#xff09; A: # B: " " C: ‘’’ ‘’’…

Java关于实例对象调用静态变量和静态方法问题

直接去看原文 原文链接:Java关于实例对象调用静态变量和静态方法问题_java对象可以调用static方法吗_骑个小蜗牛的博客-CSDN博客 --------------------------------------------------------------------------------------------------------------------------------- 实例…

2.13每日一题(根号下的定积分及去绝对值的定积分)

1、用三角函数的公式化1及二倍角公式将sinx化掉&#xff0c;构成完全平方公式 2、去根号&#xff0c;注意去根号要加绝对值&#xff0c; 3、通过区间比较sinx、cosx的大小去绝对值

vscode 保存 “index.tsx“失败: 权限不足。选择 “以超级用户身份重试“ 以超级用户身份重试。

vscode 保存 "index.tsx"失败: 权限不足。选择 “以超级用户身份重试” 以超级用户身份重试。 操作&#xff1a;mac在文件夹中创建文件&#xff0c;sudo 创建umiJs项目 解决&#xff1a;修改文件夹权限 右键文件夹