问题标签 [memento]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
3349 浏览

java - 使用备忘录模式(和命令)存储复杂对象的状态

我正在开发一个使用 Java 的小型 UML 编辑器项目,这是我几个月前开始的。几周后,我得到了一个 UML 类图编辑器的工作副本。

但是现在,我完全重新设计它以支持其他类型的图表,例如序列、状态、类等。这是通过实现一个图形构建框架来完成的(Cay Horstmann 在该主题上的工作给我很大启发紫罗兰色 UML 编辑器)。

重新设计进展顺利,直到我的一位朋友告诉我,我忘记在项目中添加 Do/Undo 功能,在我看来,这是至关重要的。

想起面向对象的设计课程,我立刻想到了 Memento 和 Command 模式。

这是交易。我有一个抽象类 AbstractDiagram,它包含两个 ArrayList:一个用于存储节点(在我的项目中称为 Elements),另一个用于存储边缘(在我的项目中称为 Links)。该图可能会保留一堆可以撤消/重做的命令。很标准。

如何有效地执行这些命令?比如说,我想移动一个节点(该节点将是一个名为 INode 的接口类型,并且会有从它派生的具体节点(ClassNode、InterfaceNode、NoteNode 等))。

位置信息作为属性保存在节点中,因此通过修改节点本身中的属性,状态会改变。刷新显示时,节点将移动。这是模式的 Memento 部分(我认为),不同之处在于对象是状态本身。

此外,如果我保留原始节点的克隆(在它移动之前),我可以回到它的旧版本。相同的技术适用于节点中包含的信息(类或接口名称、注释节点的文本、属性名称等)。

问题是,在图中,如何在撤消/重做操作时将节点替换为其克隆?如果我克隆图表引用的原始对象(在节点列表中),则克隆不是图表中的引用,唯一指向的是命令本身!我是否应该在图中包含根据 ID 查找节点的机制(例如),以便我可以在图中用其克隆替换节点(反之亦然)?是否由 Memento 和 Command 模式来做到这一点?链接呢?它们也应该是可移动的,但我不想只为链接创建一个命令(一个只为节点创建一个命令),我应该能够根据命令对象的类型修改正确的列表(节点或链接)指的是。

你将如何进行?简而言之,我无法以命令/备忘录模式表示对象的状态,以便可以有效地恢复它并在图表列表中恢复原始对象,具体取决于对象类型(节点或链接)。

非常感谢!

纪尧姆。

PS:如果我不清楚,请告诉我,我会澄清我的信息(一如既往!)。

编辑

这是我在发布此问题之前开始实施的实际解决方案。

首先,我有一个 AbstractCommand 类定义如下:

然后,使用 AbstractCommand 的具体派生来实现每种类型的命令。

所以我有一个移动对象的命令:

我还有一个 MoveRemoveCommand(用于...移动或删除对象/节点)。如果我使用 instanceof 方法的 ID,我不必将图表传递给实际的节点或链接,以便它可以将自己从图表中移除(我认为这是一个坏主意)。

AbstractDiagram 图;可添加对象;AddRemoveType 类型;

最后,我有一个 ModificationCommand,用于修改节点或链接的信息(类名等)。这可能在将来与 MoveCommand 合并。这个类暂时是空的。我可能会使用一种机制来确定修改后的对象是节点还是边(通过 instanceof 或 ID 中的特殊表示)来执行 ID 操作。

这是一个好的解决方案吗?

0 投票
4 回答
636 浏览

.net - .NET 上的纪念品实现

我在 .NET 上看到过两种不同的 memento 实现。

一个非常简单——对象创建了它自己的另一个实例。

另一种是使用 BinaryFormatter 和 MemoryStream 序列化对象。

哪个是首选方法?谁能指出每种方法的优缺点?


顺便说一句,我有兴趣从资源使用/开发人员生产力的角度来看待它。我很抱歉没有先说明这一点。

假设 memento 不需要持久化,哪个是首选?

从开发人员生产力的角度来看,序列化胜出。对于任何对象来说,几行通用的代码比手动创建一个可能涉及私有构造函数、字段分配等的克隆更有效。

但话又说回来,也许连载很重——我不确定。

0 投票
3 回答
5047 浏览

design-patterns - 对对象进行版本控制有哪些设计模式?

有哪些设计模式可以在对象更改时保留其历史记录。我不需要像事件溯源那样繁重的任务,只需要在特定事件发生时保存过去版本的能力(在这种情况下,当按下打印表单按钮时)。

0 投票
7 回答
62471 浏览

c# - 如何为 TextBox 实现良好且高效的撤消/重做功能

我有一个文本框,我想为其实现撤消/重做功能。我读过它可能已经有一些轻微的撤消功能,但是它有问题吗?无论如何,我想同时实现撤消和重做功能,只是为了了解您将如何继续执行此操作。

我已经阅读了有关Memento 模式的内容,并在 CodeProject上的通用撤消/重做示例中查看了一些内容。而且这种模式很有意义。我似乎无法理解如何实现它。以及如何有效地处理TextBox.

当然,我可以只存储textbox.Textwhen TextChanges,但这会很快占用大量内存,尤其是在TextBox包含大量文本的情况下。

所以无论如何,我正在寻找一些关于如何实现一个好的、清晰和有效的方式来实现这个功能的建议。一般而言,尤其是对于 TextBox c",)

0 投票
2 回答
494 浏览

design-patterns - Memento 的正确实现

在 memento 设计模式中,将 Caretaker 作为 Originator 的聚合是错误的吗?

0 投票
2 回答
4091 浏览

javascript - Javascript 中的备忘录

我正在寻找用于 CRUD 表单的备忘录模式 (GoF) 的 JavaScript 实现。在其基本级别中,撤消对输入的更改就足够了,但是将它与 YUI 或 Ext 等标准 JS 框架一起使用来撤消和重做网格操作(新行、删除行等)会很棒。

谢谢

0 投票
1 回答
488 浏览

java - VBA 中的备忘录实现

我正在寻找 Memento 模式 (GoF) 的 VBA 实现。我正在考虑从 Wikipedia转换 Java 版本。它将用于 Excel 加载项的撤消/重做功能。

具体来说,我对这条线有困难:

或者,为了更具体,有人可以在 VBA 中重写它:

我试图转换的整个代码都可以在上面的 Wikipedia 链接中找到。

谢谢

0 投票
2 回答
2044 浏览

c# - 比较两个对象状态,更新前后

第一件事。我有以下课程:

}

我在winforms中使用升C。我的应用程序的前端在左侧有一个列表框,其中包含员工的名字。在左侧,有不同的文本框对应于列表框中选择的员工。我以这样一种方式对其进行了编码,每次我选择一个员工时,它的属性,如员工 ID、姓名、职位等都会显示在这些字段中。

如果用户更改员工的任何属性,他必须单击更新按钮才能对数据库进行更改。现在真正的问题是,当用户更改所选员工的任何字段并选择另一个员工而不单击更新按钮时,我想显示一个弹出框告诉用户如果他选择另一个员工,所有更改都将是丢失。

出于这个原因,我创建了 momento 类来保存员工的先前状态。我也尝试过重载 == 运算符

我的想法是比较这两个对象......但我没有成功。我该怎么做?如果进行了更改,我如何显示弹出窗口。?我在哪里放置代码以显示弹出窗口?

0 投票
3 回答
298 浏览

design-patterns - 如何在备忘录模式中创建备忘录的默认实例?

我使用备忘录模式来保存多实例表单的属性,其中 n 个表单由用户在父表单内创建。备忘录的目的是在用户关闭并稍后重新打开父表单时重新获得相同数量的表单及其设置。表单纪念品的保存是通过父表单上的“保存”按钮完成的。所以我有两个挑战..

  1. 我需要在打开新表单时使用一组默认属性,那么我在哪里设置这些默认值.. 在备忘录的默认空构造函数中,或者在 Originator 的某个地方(在哪里?)?
  2. 接下来,我希望用户能够更改默认值,从而制作自己的默认纪念品。这是如何/在哪里保存的,我如何确定是否设置了这种默认纪念品?

当然我可能会调整它以某种方式工作,但我想知道是否有一个通用的模式描述可以解决这个问题,这样我就有一个坚定的指导方针可以遵循。

干杯!

0 投票
2 回答
1649 浏览

java - DTO 模式与 Memento 模式

DTO 模式(由 Fowler 提出)和Memento 模式(由 GoF 提出)在动机和实现方面有什么区别?可以是同一个班吗?如果是,我该如何命名它们(xxxDTO 或 xxxMemento)?它们在实施上有什么主要区别吗?他们在MVP架构中的位置在哪里?

谢谢。