当前位置: 首页 > news >正文

【前端设计模式】之备忘录模式

备忘录模式是一种行为设计模式,它允许在不破坏封装性的前提下捕获和恢复对象的内部状态。在前端开发中,备忘录模式可以用于保存和恢复用户界面的状态,以及实现撤销和重做功能。

备忘录模式特性:

  1. 封装了对象的状态:备忘录对象可以保存原始对象的内部状态,并且只有原始对象可以访问该状态。
  2. 可以恢复对象的状态:备忘录对象可以将保存的状态重新应用到原始对象上,使其恢复到之前的状态。
  3. 不破坏封装性:备忘录模式通过将状态保存在备忘录对象中,避免了直接暴露原始对象的内部状态。

应用示例

1. 保存表单数据:

 
// 备忘录
class FormMemento {constructor(state) {this.state = state;}
}// 原始对象
class Form {constructor() {this.state = {};}save() {return new FormMemento(this.state);}restore(memento) {this.state = memento.state;}
}// 使用示例
const form = new Form();
form.state = { name: 'John', age: 25 };const memento = form.save();form.state = { name: 'Alice', age: 30 };form.restore(memento);
console.log(form.state); // { name: 'John', age: 25 }

上述代码中,Form类表示一个表单对象,FormMemento类表示表单的备忘录对象。通过调用save方法可以保存表单的状态,调用restore方法可以恢复表单到之前的状态。

  1. FormMemento类:这是一个简单的类,它只有一个属性,即state。这个类的作用是保存表单(Form)对象的状态。

  2. Form类:这个类具有一个state属性,它是一个对象,用于存储表单的状态。这个类有两个方法:

    • save()方法:此方法创建并返回一个FormMemento对象,该对象包含当前Form对象的状态。
    • restore(memento)方法:此方法接受一个FormMemento对象,并将其状态复制到当前Form对象中。
  3. 使用示例:首先,创建一个新的Form对象。然后,设置其状态,调用save()方法保存当前状态,更改状态,最后使用restore()方法恢复到之前保存的状态。

2. 撤销和重做功能

 
// 备忘录
class EditorMemento {constructor(content) {this.content = content;}
}// 原始对象
class Editor {constructor() {this.content = '';this.history = [];this.currentIndex = -1;}type(text) {this.content += text;}save() {const memento = new EditorMemento(this.content);this.history.push(memento);this.currentIndex++;}undo() {if (this.currentIndex > 0) {this.currentIndex--;this.content = this.history[this.currentIndex].content;}}redo() {if (this.currentIndex < this.history.length - 1) {this.currentIndex++;this.content = this.history[this.currentIndex].content;}}
}// 使用示例
const editor = new Editor();
editor.type('Hello');
editor.save();
console.log(editor.content); // 'Hello'editor.type(' World');
editor.save();
console.log(editor.content); // 'Hello World'editor.undo();
console.log(editor.content); // 'Hello'editor.redo();
console.log(editor.content); // 'Hello World'

上述代码中,首先定义了一个EditorMemento类,表示编辑器的备忘录。备忘录对象保存了编辑器在某个状态下的内容。

接下来定义了一个Editor类,表示编辑器对象。编辑器对象包含一个内容属性content,一个历史记录属性history,以及一个当前索引属性currentIndex

编辑器对象提供了几个方法:

  • type(text):在编辑器中输入文本,将文本追加到内容属性中。
  • save():保存当前编辑器的状态,创建一个新的备忘录对象,并将其添加到历史记录中。同时更新当前索引的值。
  • undo():撤销上一次的操作,将当前索引减1,并将内容属性更新为上一次保存的备忘录中的内容。
  • redo():重做上一次撤销的操作,将当前索引加1,并将内容属性更新为下一次保存的备忘录中的内容。

优缺点

优点
  1. 提供了一种保存和恢复对象状态的方式,使得对象的状态管理更加灵活。
  2. 可以实现撤销和重做功能,提升用户体验。
  3. 不破坏封装性,保持了对象的内部状态的私有性。
缺点
  1. 如果备忘录对象过多或者状态较大,会占用较大的内存空间。
  2. 备忘录模式会增加代码复杂度,需要额外维护备忘录对象和原始对象之间的关系。

总结

备忘录模式是一种有用的设计模式,在前端开发中可以应用于保存和恢复用户界面状态、实现撤销和重做功能等场景。通过封装对象状态并提供恢复机制,备忘录模式提高了代码灵活性和可维护性。然而,在使用备忘录模式时需要注意内存占用和代码复杂度等问题。

相关文章:

【前端设计模式】之备忘录模式

备忘录模式是一种行为设计模式&#xff0c;它允许在不破坏封装性的前提下捕获和恢复对象的内部状态。在前端开发中&#xff0c;备忘录模式可以用于保存和恢复用户界面的状态&#xff0c;以及实现撤销和重做功能。 备忘录模式特性&#xff1a; 封装了对象的状态&#xff1a;备…...

复习Day15:栈与队列part02:20. 有效的括号、1047.删除字符串中所有相邻重复项

我用的方法是在leetcode再过一遍例题&#xff0c;明显会的就复制粘贴&#xff0c;之前没写出来就重写&#xff0c;然后从拓展题目中找题目来写。辅以Labuladong的文章看。然后刷题不用CLion了&#xff0c;使用leetcode自带的IDE模拟面试环境。 历史博客链接&#xff1a; http…...

基于Java的宠物商城管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…...

Python的GIL存在的情况下,是否还有必要添加线程锁。

GIL锁的产生&#xff1a; 为了保证在单线程情况下&#xff0c;Python的正常执行和效率&#xff0c;GIL锁产生了&#xff0c;由于只有一把锁就不会产生死锁也不用切换。 对于Python语言而言&#xff0c;只有CPython解释器&#xff08;用C语言编写的Python解释库&#xff09;存在…...

基于下垂控制的孤岛双机并联逆变器环流抑制MATLAB仿真模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 在实际应用中逆变器都是并联运行的,但是逆变器的并联运行也存在不少问题,由于线路阻抗差异、各个逆变器输出端瞬时电压幅值不同等,都容易导致环流的出现。环流会导致逆变器损耗增加,从而影响微电网的输出效率…...

spring事务面试题

1.Spring 事务实现方式有哪些&#xff1f; 事务就是一系列的操作原子操作,Spring事务机制主要 包括声明式事务和编程式事务。 编程式事务&#xff1a;通过编程的方式管理事务&#xff0c;自己设置未提交模式&#xff0c;自己获取连接&#xff0c;自己预编译&#xff0c;自己回…...

C++标准库算法整理

目录 1、数值操作 1.1、std::accumulate 1.2、std::inner_product 1.3、std::partial_sum 1.4、std::exclusive_scan 1.5、std::inclusive_scan 1.6、std::reduce 2、相邻元素 2.1、std::adjacent_difference 2.2、std::adjacent_find 2.3、std::unique 2.4、std::u…...

【Codeforces】Codeforces Round 903 (Div. 3)【待补】

Dashboard - Codeforces Round 903 (Div. 3) - Codeforces Problem - C - Codeforces Problem - D - Codeforces...

workerman 运行时报错 Call to undefined function posix_getpid()

使用 验证php扩展是否齐全 curl -Ss https://www.workerman.net/check | php缺少posix 下载 在 Linux 系统上&#xff0c;可以使用包管理器来安装 php-posix 扩展&#xff0c;例如 Ubuntu 系统可以通过以下命令进行安装&#xff1a; sudo apt-get install php-posix如果你使用…...

【探讨C++中的临时对象:一时之物还是永恒之道?】

在C编程中&#xff0c;临时对象是一个经常引起讨论的话题。它们是什么&#xff0c;为什么它们存在&#xff0c;以及如何正确使用它们&#xff1f;本文将深入探讨C中的临时对象&#xff0c;帮助您理解它们的含义和用途。 什么是临时对象&#xff1f; 临时对象&#xff08;Temp…...

二叉树相关算法

1、二叉树基本操作 二叉树的定义就不在这里多说了&#xff0c;下面这个图就是一个简单的二叉树&#xff1a; 二叉树的三种遍历方式&#xff1a; 前序遍历&#xff1a;头左右&#xff0c;也就是先头后左再右&#xff1a;1245367 public static void prePrint(BinaryTreeNode …...

Vue_Bug npm install报错 code:128

Bug描述&#xff1a; npm install报错 code&#xff1a;128 npm ERR! Warning: Permanently added ‘github.com’ (ED25519) to the list of known hosts. npm ERR! gitgithub.com: Permission denied (publickey). npm ERR! fatal: Could not read from remote repository. n…...

【Unity ShaderGraph】| 如何快速制作一个 马赛克效果 实战

前言 【Unity ShaderGraph】| 如何快速制作一个 马赛克效果 实战一、效果展示二、马赛克效果四、应用实例 前言 本文将使用Unity 的ShaderGraph制作一个马赛克的效果&#xff0c;可以直接拿到项目中使用。对ShaderGraph还不了解的小伙伴可以参考这篇文章&#xff1a;【Unity S…...

【Java 进阶篇】JavaScript DOM Document对象详解

在前端开发中&#xff0c;DOM&#xff08;文档对象模型&#xff09;扮演着重要的角色。它允许我们使用JavaScript来与网页文档进行交互&#xff0c;实现动态的网页效果。DOM的核心部分之一就是Document对象&#xff0c;它代表了整个HTML文档。在本篇博客中&#xff0c;我们将深…...

LetCode刷题[简单题](5)按摩师,迭代出最优解(卡尔曼滤波也是类似迭代)

所有的遍历寻求有条件约束的最大值都可以转换成&#xff0c;新的数带来的最大值的变化&#xff0c;问题往这个方向转化就可以&#xff0c;问题都是在最中进行选择的&#xff0c;因此关注的问题最大值得上限就好了&#xff0c;不必关注可能随机的下限。关注随机可能的下限会把问…...

C/C++笔试易错与高频题型图解知识点(二)—— C++部分(持续更新中)

目录 1.构造函数初始化列表 1.1 构造函数初始化列表与函数体内初始化区别 1.2 必须在初始化列表初始化的成员 2 引用&引用与指针的区别 2.1 引用初始化以后不能被改变&#xff0c;指针可以改变所指的对象 2.2 引用和指针的区别 3 构造函数与析构函数系列题 3.1构造函数与析…...

使用new创建动态结构

在运行时创建数组优于在编译时创建数组&#xff0c;对于结构&#xff08;同一个结构可以存储多种类型的数据。&#xff09;也是如此。需要在程序运行时为结构分配所需的空间&#xff0c;这也可以使用new运算符来完成。通过使用new&#xff0c;可以创建动态结构。同样&#xff0…...

论文笔记与复现[156]PARAFAC. tutorial and applications

原文下载&#xff1a;https://www.sciencedirect.com/science/article/abs/pii/S0169743997000324 摘要 本文介绍了PARAFAC的多维分解方法及其在化学计量学中的应用。PARAFAC是PCA向高阶数组的推广&#xff0c;但该方法的一些特性与普通的二维情况截然不同。例如&#xff0c;…...

Python 基础30道测试题

你好&#xff0c;我是悦创。 我会给出 30 道涉及 Python 基础的题目。这些题目将覆盖各种 Python 基础知识点&#xff0c;包括数据类型、控制结构、函数、模块等。 输出 “Hello, World!”。创建一个变量&#xff0c;并为其赋值&#xff0c;然后输出该变量的值。输入两个数&a…...

【环境搭建】linux docker-compose安装rocketmq

创建目录 mkdir -p /data/docker/rocketmq/namesrv/logs mkdir -p /data/docker/rocketmq/broker1/conf mkdir -p /data/docker/rocketmq/broker1/logs mkdir -p /data/docker/rocketmq/broker1/store 给权限 chmod -R 777 /data/docker/rocketmq 创建配置文件 cd /data/d…...

AI系统的四层缓存架构

别再被“提示词缓存”“语义缓存”绕晕了&#xff0c;它们根本不是一回事 先上关系图&#xff1a;AI系统里的四层缓存 很多人把缓存当一个东西聊&#xff0c;其实它们是四个不同的层&#xff0c;各管各的&#xff0c;又互相喂数据。 第一层 长期知识源 项目记忆缓存&#x…...

AssetRipper:3步解锁Unity游戏资源逆向提取的终极免费方案

AssetRipper&#xff1a;3步解锁Unity游戏资源逆向提取的终极免费方案 【免费下载链接】AssetRipper GUI Application to work with engine assets, asset bundles, and serialized files 项目地址: https://gitcode.com/GitHub_Trending/as/AssetRipper 在Unity游戏开发…...

给新手的保姆级教程:在VMware里一步步装好Ubuntu Server 22.04 LTS(附静态IP和SSH配置)

虚拟化环境下的Ubuntu Server 22.04 LTS全流程部署指南 对于刚接触Linux服务器运维的新手而言&#xff0c;在虚拟化环境中搭建Ubuntu Server是一个理想的起点。不同于物理机安装&#xff0c;虚拟化平台提供了可重复、隔离的实验环境&#xff0c;让学习者能够大胆尝试而无需担心…...

DeepSeek LeetCode 2508.添加边使所有节点度数都为偶数 public boolean isPossible(int n, List<List<Integer>> edges)

问题分析我们需要判断能否添加至多两条边&#xff08;不能添加重复边&#xff0c;不能添加自环&#xff09;&#xff0c;使得图中所有节点的度数都为偶数。---思路步骤1. 统计每个节点的当前度数遍历给出的边&#xff0c;统计每个节点的度数。 2. 找出度数为奇数的节点设奇数度…...

终极IDE评估周期管理方案:开源ide-eval-resetter完整解析

终极IDE评估周期管理方案&#xff1a;开源ide-eval-resetter完整解析 【免费下载链接】ide-eval-resetter 项目地址: https://gitcode.com/gh_mirrors/id/ide-eval-resetter 在当今快节奏的开发环境中&#xff0c;JetBrains IDE系列产品凭借其卓越的代码智能和丰富的功…...

别再硬套RBAC了!用Filebrowser的‘文件夹规则’搞定多级文件权限(附实战配置)

别再硬套RBAC了&#xff01;用Filebrowser的‘文件夹规则’搞定多级文件权限&#xff08;附实战配置&#xff09; 在权限管理的世界里&#xff0c;RBAC&#xff08;基于角色的访问控制&#xff09;早已成为行业标准&#xff0c;但你是否遇到过这样的场景&#xff1a;一个只有三…...

即时通讯IM:从聊天工具到企业数字底座

即时通讯IM在2026年已不再只是员工桌面上用来收发消息的软件。它正经历一场深刻的角色蜕变——从“聊天工具”升级为支撑企业核心业务运转的“数字底座”。即时通讯系统已成为支撑企业核心运营的关键基础设施&#xff0c;IM正在被赋予连接一切、打通信息流的关键角色。 这种进化…...

深入GD32F427的ENET外设:如何为你的LAN8720 PHY芯片选择正确的RMII时钟模式(REF_CLK In vs Out)

深入解析GD32F427与LAN8720的RMII时钟架构设计 在嵌入式以太网开发中&#xff0c;时钟信号的稳定性往往决定着整个通信系统的可靠性。当GD32F427微控制器通过RMII接口与LAN8720 PHY芯片协同工作时&#xff0c;REF_CLK时钟模式的选择不仅影响硬件成本&#xff0c;更直接关系到信…...

嵌入式Linux下MT7601U无线网卡驱动移植与网络配置实战

1. 项目概述最近在做一个基于Linux 3.5内核的嵌入式项目&#xff0c;需要让开发板通过USB接口连接无线网络。手头正好有几个闲置的360随身WiFi&#xff0c;查了一下&#xff0c;它的核心芯片是联发科&#xff08;MediaTek&#xff09;的MT7601U&#xff0c;这是一款非常经典的U…...

从游戏动作到影视特效:Blender Python骨骼动画脚本的跨界实战指南

从游戏动作到影视特效&#xff1a;Blender Python骨骼动画脚本的跨界实战指南 在数字内容创作领域&#xff0c;骨骼动画是连接游戏开发与影视特效的核心技术纽带。无论是独立游戏开发者需要将角色动作导出到Unity引擎&#xff0c;还是影视动画师希望批量处理动作捕捉数据&#…...