2012-01-05 60 views
2

我负责维护使用Swing编写的旧应用程序,并结合使用Java3D编写的类似CAD的工具。我们在内存使用情况有问题。分析后,这与应用程序中的撤消功能有关。Swing/Java3D应用程序中基于状态的撤消:AOP解决方案?

所有取消的功能是基于状态的,有这样一个基本概念:创建这些UndoActions

public class UndoAction { 
    private UndoTarget target; 
    private Object old_data; 
    private Object new_data; 
} 

代码在整个应用程序基本上散落。因为有新的对象,现有对象的修改和子树的修改的修改之间没有区别,会发生以下情况:

会发生什么事是一个单一的动作如下:

  • 创建一个新的对象A
  • 修改对象的字段foo。新的UndoAction被放置在包含foo_old和foo_new的堆栈中。
  • 修改该对象的字段bar。新的UndoAction被放置在堆栈上,其中包含bar_old和bar_new。
  • 执行B.setField(A)。新的UndoAction被放置在包含field_old和field_new(== A)的堆栈中。

根本没有粒度或任何控制。这根本无助于可维护性。

我想重构这个系统,使它变得可维护和内存友好。不幸的是,使用Command模式来实现Undo系统是不可能的。这些行为太影响回复。我想执行以下操作:

  1. 使用注释提供“撤消划界”。 @Undoable()会将一个方法标记为生成一个放在堆栈上的UndoAction。这可以像事务一样进行参数化:REQUIRE,NEST,JOIN ...在进入Undoable方法时克隆完整对象图。
  2. 当事务(=方法)完成时,算法应该将新状态与旧状态进行比较并保存差异。
  3. 要实现这一点,我们可以使用AOP。这使我们能够保持核心代码非常干净。

的现在,我的问题: 做任何上述3种功能的Java中已经存在?我可以想象,我不是第一个与基于状态的撤消和与之相关联的问题(撤消分界,状态比较,...)

+0

AspectJ非常强大,这可能适用于你想要做的事情。 – jbranchaud 2012-01-05 15:48:13

+0

当addFirst()超过某个限制时,不能使用Deque和removeLast()吗? – trashgod 2012-01-05 18:09:00

+1

UndoStack的确切实现并不困难; Swing UndoManager对我来说很好。难点在于构建oldState和newState:克隆什么,何时将其添加到新的UndoAction以及如何确保旧数据不被引用。 – parasietje 2012-01-05 18:09:30

回答

2

在这个问题已经打开很长一段时间后,似乎问题是:“不,不存在这样的框架。”

作为其他人的指南,我正在调查Eclipse Modeling FrameworkEMF.Edit框架。在这个框架中,您使用描述语言定义模型,框架为您处理模型和任何操作。这会自动导致创建Actions和Undo/Redo。

+0

@trashgod关于3D Deque的想法非常简单,让我感到(现在) – mKorbel 2012-02-23 18:40:15

+0

@mKorbel:对不起,我的评论有点含糊,而且确实如此正如OP注意到的那样。我详细阐述了[这里](http://docs.oracle.com/javase/tutorial/uiswing/components/generaltext.html)。 – trashgod 2012-02-23 18:57:18

+0

@parasietje如果我没有记错的话,CAD/CAM是在低级别的处理器代码中生成的,因为Assembler/Cobol是 – mKorbel 2012-02-23 19:03:31

相关问题