登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
导读
排行榜
资讯
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
小组
VIP申请
VIP网盘
网盘
联系我们
发帖说明
道具
勋章
任务
淘帖
动态
分享
留言板
导读
设置
我的收藏
退出
腾讯QQ
微信登录
1
2
/ 2 页
下一页
返回列表
首页
›
业界区
›
业界
›
【备忘录设计模式详解】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
相关帖子
CompletableFuture 实战:Java 异步编程高性能实战指南
CompletableFuture 实战:Java 异步编程高性能实战指南
CompletableFuture 实战:Java 异步编程高性能实战指南
CompletableFuture 实战:Java 异步编程高性能实战指南
CompletableFuture 实战:Java 异步编程高性能实战指南
CompletableFuture 实战:Java 异步编程高性能实战指南
CompletableFuture 实战:Java 异步编程高性能实战指南
torch.nn神经网络详解
Java 中的 实现、泛型
在 React 项目中优雅实现新用户引导:HagiCode 的 driver.js 实践
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
安全
CompletableFuture 实战:Java 异步编程高性能实战指南
0
938
巴沛若
2026-03-30
安全
CompletableFuture 实战:Java 异步编程高性能实战指南
0
487
恿榫
2026-03-30
安全
CompletableFuture 实战:Java 异步编程高性能实战指南
0
530
汲佩杉
2026-03-30
安全
CompletableFuture 实战:Java 异步编程高性能实战指南
0
500
高小雨
2026-03-30
安全
CompletableFuture 实战:Java 异步编程高性能实战指南
0
95
雌鲳签
2026-03-30
安全
CompletableFuture 实战:Java 异步编程高性能实战指南
0
635
阎怀慕
2026-03-30
安全
CompletableFuture 实战:Java 异步编程高性能实战指南
0
245
鸳剿
2026-03-30
业界
torch.nn神经网络详解
0
4
雌鲳签
2026-03-31
安全
Java 中的 实现、泛型
0
497
殳世英
2026-03-31
业界
在 React 项目中优雅实现新用户引导:HagiCode 的 driver.js 实践
0
428
浅皮懔
2026-04-01
回复
(24)
挽幽
2025-10-26 23:28:48
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
感谢分享
丘娅楠
2025-10-27 03:48:46
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
感谢分享
溥价
2025-11-7 02:13:56
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
喜欢鼓捣这些软件,现在用得少,谢谢分享!
奚娅琼
2025-12-23 18:56:58
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
喜欢鼓捣这些软件,现在用得少,谢谢分享!
稿辏付
2025-12-28 22:29:03
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
感谢分享,学习下。
戟铵腴
2026-1-5 06:42:37
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
东西不错很实用谢谢分享
坡琨
2026-1-19 23:27:05
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
谢谢楼主提供!
荏牌
2026-1-21 12:10:55
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
感谢发布原创作品,程序园因你更精彩
陆菊
2026-1-26 03:44:26
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
喜欢鼓捣这些软件,现在用得少,谢谢分享!
厂潺
2026-1-27 01:53:00
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
收藏一下 不知道什么时候能用到
兑谓
2026-1-30 06:34:24
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
不错,里面软件多更新就更好了
替攀浮
2026-2-1 05:49:46
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
谢谢楼主提供!
缢闸
2026-2-2 02:55:01
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
新版吗?好像是停更了吧。
旌磅箱
2026-2-2 17:15:47
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
分享、互助 让互联网精神温暖你我
零幸
2026-2-3 08:31:22
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
这个有用。
歇凛尾
2026-2-3 11:15:09
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
收藏一下 不知道什么时候能用到
卢莹洁
2026-2-6 04:12:54
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
感谢发布原创作品,程序园因你更精彩
湛恶
2026-2-8 12:46:19
回复
使用道具
举报
照妖镜
猛犸象科技工作室:
网站开发,备案域名,渗透,服务器出租,DDOS/CC攻击,TG加粉引流
新版吗?好像是停更了吧。
荡俊屯
2026-2-10 09:12:10
回复
使用道具
举报
照妖镜
程序园永久vip申请,无限下载程序园所有程序/软件/数据/等
过来提前占个楼
下一页 »
1
2
/ 2 页
下一页
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
浏览过的版块
安全
签约作者
程序园优秀签约作者
发帖
呵烘稿
2026-2-10 09:12:10
关注
0
粉丝关注
26
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
3934307807
991125
anyue1937
9994892
kk14977
6845359
4
xiangqian
638210
5
神泱
9539
6
宋子
9880
7
韶又彤
9911
8
注思
9034
9
荪俗
9023
10
诀锺
9036
查看更多
今日好文热榜
72
记一次Webshell流量分析2 | 添柴不加火
451
记一次Webshell流量分析2 | 添柴不加火
136
记一次Webshell流量分析2 | 添柴不加火
725
记一次Webshell流量分析2 | 添柴不加火
66
记一次Webshell流量分析2 | 添柴不加火
405
AI元人文:在荆棘中开路——对四个实践性追
928
记一次Webshell流量分析2 | 添柴不加火
0
Python模块与包管理完全指南:从入门到精通
420
记一次Webshell流量分析2 | 添柴不加火
0
Python模块与包管理完全指南:从入门到精通
268
AI元人文:在荆棘中开路——对四个实践性追
575
记一次Webshell流量分析2 | 添柴不加火
84
记一次Webshell流量分析2 | 添柴不加火
158
记一次Webshell流量分析2 | 添柴不加火
874
记一次Webshell流量分析2 | 添柴不加火
146
记一次Webshell流量分析2 | 添柴不加火
824
记一次Webshell流量分析2 | 添柴不加火
497
AI元人文:在荆棘中开路——对四个实践性追
873
记一次Webshell流量分析2 | 添柴不加火
150
记一次Webshell流量分析2 | 添柴不加火