0

私のアプリケーションには、潜在的に大量のデータを含む多次元配列があるため、ユーザーが変更するたびにそのオブジェクトを完全に保存することは不可能に思えます。

コマンドパターンについて読んで、最終的にこの記事を見つけましたが、よくわかりません。彼のコード例がどのように機能するのか、そしてこれが私のアプリケーションで機能するかどうかはわかりません。また、この「新しい」方法はGoFパターンよりも好ましいですか?

私のアプリケーションには、現在のドキュメントで機能するブラシや塗りつぶしツールなどのツールがあり、元に戻す/やり直し機能を最適に実装する方法はよくわかりませんが、すべての操作でオブジェクトの状態を保存しても、無限の元に戻すことはできません。やり直しは私が求めているものです。コマンドパターンをこのコンテキストで使用できるかどうか、または記事の実装がどのように機能するかはわかりません。

うまくいけば、誰かが記事を詳しく説明したり、コマンドパターンを私のニーズにどのように適合させることができるかを説明したりできます。読んでくれてありがとう!

4

2 に答える 2

1

3つの値(location、oldvalue、newvalue、locationは多次元配列の要素を指す)と2つのメソッド(undo、redo)を使用してクラスを作成します。各操作で、変更される大きな配列内の要素ごとにこれらのオブジェクトの配列を作成し、それを元に戻るスタックにプッシュします。UNDOスタックをポップオフするときは、undoを呼び出してから、REDOスタックにプッシュします。REDOポップの反対です。新しいアクションでREDOスタックをクリアすることを忘れないでください。

編集:

サンプル:

public void undo()
{
    location = oldvalue;
}

public void redo()
{
    location = newvalue;
}

そして、スタックの例:

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

少し調べてみると、いくつかの可能な解決策が見つかります。最も単純なのは、おそらくスタックを使用することです。もう1つは、mementoパターンを使用することです。ただし、ここでコマンドパターンについて質問したので、簡単な例を示します。

これは基本的に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のインスタンスに対して2つの「アクション」を実行します(コマンドパターンを実装します)。

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 に答える