0

在我的应用程序中有一个多维数组,其中可能包含大量数据,因此每次用户更改时完全保存该对象似乎是不可行的。

我阅读了命令模式并最终找到了这篇文章,但我不太了解它。我不确定他的代码示例是如何工作的,以及这是否适用于我的应用程序。此外,这种“新”方法是否比 GoF 模式更可取?

我的应用程序具有适用于当前文档的画笔和填充工具等工具,我不确定如何最好地实现撤消/重做功能,但我知道为每个操作保存对象的状态不会允许无限撤消和重做,这就是我所追求的。我不确定命令模式是否可以在这种情况下使用,或者文章的实现是否以及如何工作。

希望有人可以详细说明这篇文章,或者解释一下命令模式如何适应我的需要。谢谢阅读!

4

2 回答 2

1

只需做一点研究,我就会找到一些可能的解决方案。最简单的可能是使用堆栈。另一种是使用纪念品模式。但是,既然您在这里询问了命令模式,那么您就是一个简单的示例。

这基本上取自 codeprojects 示例。

class Document
{
   private List<string> _textArray = new List<string>();

   public void Write(string text)
   {
       _textArray.Add(text);
   }
   public void Erase(string text)
   {
       _textArray.Remove(text);
   }
   public void Erase(int textLevel)
   {
       _textArray.RemoveAt(textLevel);
   }

   public string ReadDocument()
   {
       System.Text.StringBuilder sb = new System.Text.StringBuilder();
       foreach(string text in _textArray)
           sb.Append(text);
       return sb.ToString();
   }
}

abstract class Command
{        
   abstract public void Redo();
   abstract public void Undo();
}

class DocumentEditCommand : Command
{
   private Document _editableDoc;
   private string _text;

   public DocumentEditCommand(Document doc, string text)
   {
       _editableDoc = doc;
       _text = text;
       _editableDoc.Write(_text);
    }
   override public void Redo()
   {
       _editableDoc.Write(_text);
   } 
   override public void Undo()
   {
       _editableDoc.Erase(_text);
   }
}

class DocumentInvoker
{
   private List<Command> _commands = new List<Command>();

   private Document _doc = new Document();

   public void Redo( int level )
   {
       Console.WriteLine( "---- Redo {0} level ", level );
       ((Command)_commands[ level ]).Redo();
   }

   public void Undo( int level )
   {
       Console.WriteLine( "---- Undo {0} level ", level );
       ((Command)_commands[ level ]).Undo();
   }

   public void Write(string text)
   {
       DocumentEditCommand cmd = new 
       DocumentEditCommand(_doc,text);
       _commands.Add(cmd);
   }

   public string Read()
   {
      return _doc.ReadDocument();
   }
}

使用命令模式。

我们对 documentinvoker 的实例执行两个“操作”(实现我们的命令模式)。

DocumentInvoker instance = new DocumentInvoker ();
instance.Write("This is the original text.");
instance.Write(" Here is some other text.");

现在我们可以撤消这些操作。

instance.Undo(1);

文档中的文本现在将是。

---- Undo 1 level
This is the original text.

现在我们可以重做这个动作

instance.Redo(1);

文本将。

---- Redo 1 level
This is the original text. Here is some other text.

显然,您需要对其进行修改以满足您的需求。如果您想要更多解释,请查看文章http://www.codeproject.com/KB/books/DesignPatterns.aspx

于 2011-08-09T14:10:19.153 回答
1

创建一个包含三个值(location、oldvalue 和 newvalue,其中 location 指向多维数组中的一个元素)和两个方法(撤消、重做)的类。在每个操作中,为大型数组中发生变化的每个元素创建一个包含这些对象的数组,并将其推送到撤消堆栈上。弹出撤消堆栈时,调用撤消,然后推送到重做堆栈。与重做流行音乐相反。只需记住使用新操作清除重做堆栈。

编辑:

样本:

public void undo()
{
    location = oldvalue;
}

public void redo()
{
    location = newvalue;
}

然后是堆栈的示例:

command = undoStack.Pop();
command.undo();
redoStack.Push(command);
于 2011-08-09T13:46:10.937 回答