2011-08-09 22 views
0

私のアプリケーションには多分多量のデータを持つ多次元配列があり、ユーザーが変更するたびにそのオブジェクトを完全に保存することはできないようです。元に戻す/やり直しを実装しようとしていますが、この記事ではわかりません。助けて?

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

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

誰かが記事を詳しく説明したり、Commandパターンが私のニーズにどのように適応できるかを説明してください。読んでくれてありがとう!

答えて

1

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

EDIT:

サンプル:

public void undo() 
{ 
    location = oldvalue; 
} 

public void redo() 
{ 
    location = newvalue; 
} 

そしてスタックの例:ほんの少し研究を行う

command = undoStack.Pop(); 
command.undo(); 
redoStack.Push(command); 
+0

とても簡単です!本当にありがとう! –

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(コマンドパターンを実装する)のインスタンスに対して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の記事をご覧ください。

関連する問題