登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
导读
排行榜
资讯
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
小组
VIP申请
VIP网盘
网盘
联系我们
发帖说明
道具
勋章
任务
淘帖
动态
分享
留言板
导读
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
【备忘录设计模式详解】C/Java/JS/Go/Python/TS不同语言 ...
【备忘录设计模式详解】C/Java/JS/Go/Python/TS不同语言实现
[ 复制链接 ]
呵烘稿
2025-6-6 09:46:05
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
简介
备忘录模式(Memento Pattern)是一种结构型设计模式。这种模式就是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并放在外部存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用。
备忘录模式的角色有三个:备忘录(Memento)角色、发起人(Originator)角色、负责人(Caretaker)角色
备忘录模式是由发起人(Originator)对象负责生成状态快照,其他对象不可修改状态。再将对象状态的副本存储在一个名为备忘录(Memento)的特殊对象中。除了创建备忘录的对象外,任何对象都不能访问备忘录的内容。其他对象必须使用指定接口与备忘录进行交互,它们可以获取快照的元数据(创建时间和操作名称等),但不能获取快照中原始对象的状态。
这种限制策略允许你将备忘录保存在通常被称为负责人(Caretakers)的对象历史中。由于负责人仅通过受限接口与备忘录互动,故其无法修改存储在备忘录内部的状态。同时,发起人拥有对备忘录所有成员的访问权限,从而能随时恢复其以前的某个状态。
作用
给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
实现了内部状态的封装,除了创建它的发起人之外,其他对象都不能够访问这些状态信息,也不需要关心状态的保存细节。
简化了发起人角色,发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由负责人进行管理,符合单一职责原则。
实现步骤
创建备忘录Memento,用来记录操作状态数据的实体类。
创建发起人角色Originator,状态的制造者,也是备忘录的生成者,负责将状态写入到一个新备忘录。
创建负责人角色Caretaker,用来保存和读取备忘录的历史记录,所有备忘录均可以保存在历史中,以便恢复。
客户调用方通过Originator来生成备忘录,再通过Caretaker读取和恢复备忘录历史记录。
UML
Java代码
具体备忘录
// Memento.java 备忘录(Memento)角色,负责存储发起人传入的状态
public class Memento {
private String state;
public Memento(String state) {
System.out.println(this.getClass().getName() + "::Memento() [state = " + state + "]");
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
复制代码
发起人
// Originator.java 发起人(Originator)负责生成状态快照,即利用一个新备忘录对象将自己的内部状态存储起来
public class Originator {
private String state;
// 每次创建一个新备忘录来保存状态
public Memento saveMemento() {
System.out.println(this.getClass().getName() + "::saveMemento() [state = " + state + "]");
return new Memento(state);
}
// 从备忘录中恢复状态
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
复制代码
负责人类
// Caretaker.java 负责人(Caretaker)角色,只负责保存备忘录记录,不能修改备忘录对象的内容
public class Caretaker {
// 备忘录可以是一个记录,也可以就是一个对象,根据业务场景设置
private List<Memento> mementoList = new ArrayList<Memento>();
public void add(Memento memento) {
System.out.println(this.getClass().getName() + "::add() [memento = " + memento.getClass().getName() + "]");
mementoList.add(memento);
}
public Memento get(int index) {
return mementoList.get(index);
}
public List<Memento> getMementoList() {
return this.mementoList;
}
}
复制代码
测试调用
/*
* 备忘录模式是在不暴露对象实现细节的情况下保存和恢复对象之前的状态。
* 先声明发起人Originator,再声明负责人Caretaker,发起人生成备忘录Memento
* 通过负责人则保存备忘录历史记录,读取备忘录由负责人来完成。
*/
Originator originator = new Originator();
Caretaker careTaker = new Caretaker();
// 发起人产生一个状态
originator.setState("state1");
// 覆盖了状态,那么前面的状态未保存
originator.setState("state2");
// 发起人生成备忘录,一般添加时直接保存即可
Memento memento = originator.saveMemento();
// 负责人保添加备忘录历史记录
careTaker.add(memento);
// 直接生成备忘录并添加到负责人的备忘录列表
originator.setState("state3");
careTaker.add(originator.saveMemento());
originator.setState("state4");
careTaker.add(originator.saveMemento());
System.out.println("发起人当前的状态: " + originator.getState());
// 发起人通过负责人那里取出状态
originator.restoreMemento(careTaker.get(0));
System.out.println("第一个保存的状态: " + originator.getState());
originator.restoreMemento(careTaker.get(1));
System.out.println("第二个保存的状态: " + originator.getState());
// 遍历全部备忘录
for (int i = 0; i < careTaker.getMementoList().size(); i++) {
// 外部一般不直接访问备忘录里面的状态,而是逐个恢复备忘录,再取出状态来
originator.restoreMemento(careTaker.get(i));
System.out.println("state: " + i + ")" + originator.getState());
}
复制代码
JavaScript代码
具体备忘录
// Memento.js 备忘录(Memento)角色,负责存储发起人传入的状态
// 备忘录(Memento)角色,负责存储发起人传入的状态
export class Memento {
constructor(state) {
console.log(this.constructor.name + '::Memento() [state = ' + state + ']')
this.state = state
}
getState() {
return this.state
}
setState(state) {
this.state = state
}
}
复制代码
发起人
// Originator.js 发起人(Originator)负责生成状态快照,即利用一个新备忘录对象将自己的内部状态存储起来
import { Memento } from './Memento.js'
export class Originator {
constructor() {
this.state = undefined
}
// 每次创建一个新备忘录来保存状态
saveMemento() {
console.log(
this.constructor.name + '::saveMemento() [state = ' + this.state + ']'
)
return new Memento(this.state)
}
// 从备忘录中恢复状态
restoreMemento(memento) {
this.state = memento.getState()
}
getState() {
return this.state
}
setState(state) {
this.state = state
}
}
复制代码
负责人类
// Caretaker.js 负责人(Caretaker)角色,只负责保存备忘录记录,不能修改备忘录对象的内容
export class Caretaker {
constructor() {
// 备忘录可以是一个记录,也可以就是一个对象,根据业务场景设置
this.mementoList = []
}
add(memento) {
console.log(
this.constructor.name +
'::add() [memento = ' +
memento.constructor.name +
']'
)
this.mementoList.push(memento)
}
get(index) {
return this.mementoList[index]
}
getMementoList() {
return this.mementoList
}
}
复制代码
测试调用
import { Originator } from '../src/Originator.js'
import { Caretaker } from '../src/Caretaker.js'
export function test() {
/*
* 备忘录模式是在不暴露对象实现细节的情况下保存和恢复对象之前的状态。
* 先声明发起人Originator,再声明负责人Caretaker,发起人生成备忘录Memento
* 通过负责人则保存备忘录历史记录,读取备忘录由负责人来完成。
*/
const originator = new Originator()
const careTaker = new Caretaker()
// 发起人产生一个状态
originator.setState('state1')
// 覆盖了状态,那么前面的状态未保存
originator.setState('state2')
// 发起人生成备忘录,一般添加时直接保存即可
const memento = originator.saveMemento()
// 负责人保添加备忘录历史记录
careTaker.add(memento)
// 直接生成备忘录并添加到负责人的备忘录列表
originator.setState('state3')
careTaker.add(originator.saveMemento())
originator.setState('state4')
careTaker.add(originator.saveMemento())
console.log('发起人当前的状态: ' + originator.getState())
// 发起人通过负责人那里取出状态
originator.restoreMemento(careTaker.get(0))
console.log('第一个保存的状态: ' + originator.getState())
originator.restoreMemento(careTaker.get(1))
console.log('第二个保存的状态: ' + originator.getState())
// 遍历全部备忘录
for (let i = 0; i < careTaker.getMementoList().length; i++) {
// 外部一般不直接访问备忘录里面的状态,而是逐个恢复备忘录,再取出状态来
originator.restoreMemento(careTaker.get(i))
console.log('state: ' + i + ')' + originator.getState())
}
}
// 执行测试
;(function () {
console.log('test start:')
test()
})()
复制代码
更多语言版本
不同语言实现设计模式:https://github.com/microwind/design-pattern
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
备忘录
设计模式
详解
Java
JS
相关帖子
Java Optional 完全指南:优雅处理 null 的利器
上下文协议(MCP)Java SDK 指南
工作中常用函数详解与示例-PostgreSQL(其他数据库可能函数不一致)
JS逆向-反调试分析&debuger执行&条件断点&替换文件执行
Java函数式接口——渐进式学习
大语言模型~Ollama本地模型和java一起体验LLM
最小二乘问题详解9:使用Ceres求解非线性最小二乘
设计模式简述
JS逆向-混淆加密-识别&还原-Eval&JSFuck&JSJiaMi案例
AI Agent详解
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
业界
Java Optional 完全指南:优雅处理 null 的利器
0
972
古修蟑
2025-12-17
业界
上下文协议(MCP)Java SDK 指南
0
294
豌笆
2025-12-17
业界
工作中常用函数详解与示例-PostgreSQL(其他数据库可能函数不一致)
0
84
捐催制
2025-12-17
业界
JS逆向-反调试分析&debuger执行&条件断点&替换文件执行
0
736
殳世英
2025-12-18
业界
Java函数式接口——渐进式学习
0
500
列蜜瘘
2025-12-18
安全
大语言模型~Ollama本地模型和java一起体验LLM
0
488
裴涛
2025-12-18
业界
最小二乘问题详解9:使用Ceres求解非线性最小二乘
0
499
挚魉
2025-12-19
安全
设计模式简述
0
268
厨浴
2025-12-19
业界
JS逆向-混淆加密-识别&还原-Eval&JSFuck&JSJiaMi案例
0
458
纪晴丽
2025-12-19
业界
AI Agent详解
0
789
宓碧莹
2025-12-20
回复
(3)
挽幽
2025-10-26 23:28:48
回复
使用道具
举报
照妖镜
程序园永久vip申请,500美金$,无限下载程序园所有程序/软件/数据/等
感谢分享
丘娅楠
2025-10-27 03:48:46
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
感谢分享
溥价
2025-11-7 02:13:56
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
喜欢鼓捣这些软件,现在用得少,谢谢分享!
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
签约作者
程序园优秀签约作者
发帖
呵烘稿
2025-11-7 02:13:56
关注
0
粉丝关注
22
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
3934307807
991124
anyue1937
9994892
kk14977
6845358
4
xiangqian
638210
5
韶又彤
9997
6
宋子
9981
7
闰咄阅
9993
8
刎唇
9993
9
俞瑛瑶
9998
10
蓬森莉
9949
查看更多
今日好文热榜
957
企业级多智能体系统(MAS)架构深度研究:C
191
北京守嘉陪诊登顶2025年度陪诊行业排行 专
234
流量暴跌 96%:AI 聊天机器人正在构建危险
172
AI生成论文查重能过么?8款AI写论文软件测
508
懒人长期理财的投资系统
507
第40次CCFCSP认证邮寄
867
第40次CCFCSP认证邮寄
853
第40次CCFCSP认证邮寄
439
用 .NET MAUI 10 + VS Copilot 从 0 开发一
869
【节点】[GammaToLinearSpaceExact节点]原
378
[20251218]测试sql语句子光标的执行性能(21
496
HECTF2025
16
《C语言程序设计》琐碎知识点总结笔记
378
NGD-SLAM(三)
46
AI 领域职业发展分享总结(吴恩达新课内容
103
【面试题】数据库事务隔离与传播属性是什么
191
2025年儿童羽绒服十大名牌排名:宝妈选购指
314
2025年儿童羽绒服十大名牌排名:宝妈选购指
761
Flink源码阅读:如何生成ExecutionGraph
421
Github项目CI&CD部署