命令模式撤消/重做:我的方法有什么问题吗?

发布于 2024-10-10 20:16:34 字数 1069 浏览 3 评论 0原文

我正在寻求实现一个命令模式来支持我的应用程序中的撤消/重做。数据紧密地联系在一起,因此修改我的一些对象会产生一些下游后果,我也希望能够撤消这些后果。我主要关心的是应该将执行下游命令的代码放在哪里。例如:

class:MoveObjectCommand
{
    private hierarchicalObject:internalObject;

    public MoveObjectCommand(hierarchicalObject:newObject)
    {
        internalObject = newObject;
    }

    public Execute()
    {
        internalObject.Location = someNewLocation;

        foreach(hierarchicalObject:child in internalObject.Children)
        {
            if(someNewLocation = specialPlace)
            {
                var newCommand:MoveObjectCommand = new MoveObjectCommand(child)

                CommandManager.add(newCommand);
            }
        }

    }

    public Undo()
    {
        internalObject.location = oldLocation;
    }
}

据我所知,这样的事情会很好,但我无法理解大部分执行代码实际上应该去哪里。 hierarchicalObject 是否应该有一个 .changeLocation() 方法来添加所有后续命令,或​​者它们应该像上面一样位于命令本身中?我能想到的唯一区别是,在上面的示例中,必须调用 MoveObjectCommand 才能进行后续更改以进行处理,而另一种方式可以在不需要命令的情况下调用它,并且仍然以相同的方式处理(可能会产生负面后果)用于跟踪撤消/重做步骤)。我是不是想太多了?你会把它放在哪里以及为什么(显然这个例子并没有涵盖所有角度,但有命令模式的一般最佳实践吗?)。

I'm looking to implement a command pattern to support undo/redo in my application. The data is very closely tied together, so there are some downstream consequences of modifying some of my objects that I also want to be able to undo. My main concern is where I should put the code that executes the downstream commands. For example:

class:MoveObjectCommand
{
    private hierarchicalObject:internalObject;

    public MoveObjectCommand(hierarchicalObject:newObject)
    {
        internalObject = newObject;
    }

    public Execute()
    {
        internalObject.Location = someNewLocation;

        foreach(hierarchicalObject:child in internalObject.Children)
        {
            if(someNewLocation = specialPlace)
            {
                var newCommand:MoveObjectCommand = new MoveObjectCommand(child)

                CommandManager.add(newCommand);
            }
        }

    }

    public Undo()
    {
        internalObject.location = oldLocation;
    }
}

As far as I can tell, something like this would work be fine, but I can't wrap my head around where the majority of the execution code should actually go. Should the hierarchicalObject have a .changeLocation() method that adds all the subsequent commands, or should they be in the command itself like it is above? The only difference I can think of is that in the example above, the MoveObjectCommand would have to be called for subsequent changes to process, whereas the other way it could be called without needing a command and still process the same way (could have negative consequences for tracking undo/redo steps). Am I overthinking this? Where would you put it and why (obviously this example doesn't hit all angles, but any general best practices with the command pattern?).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不气馁 2024-10-17 20:16:34

听起来你应该在模型中使用changeLocation()方法(我认为是hierarchicalObject)。只需将新位置和对象存储在命令中即可。

对于撤消/重做,您将需要一两个命令列表。

听起来你的hierarchicalObject可能是一个http://en.wikipedia.org/wiki/Composite_pattern,所以看一下四人帮书中的宏命令。另请参阅:http://en.wikipedia.org/wiki/Command_pattern

Christopher Alexander 说:“每种模式都描述了一个在我们的环境中反复出现的问题,然后描述了该问题解决方案的核心,这样您就可以使用该解决方案一百万次,而无需执行任何操作以同样的方式两次”。

sounds like you should have the changeLocation() method in the model (hierarchicalObject i presume). just store the new location and the object in the command.

for undo/redo you will need a list or two for commands.

sound like your hierarchicalObject may be a http://en.wikipedia.org/wiki/Composite_pattern, so have a take a look at the macro command in the gang-of-four book. also review: http://en.wikipedia.org/wiki/Command_pattern.

Christopher Alexander says: "Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文