2011-08-09 2 views
0

Dans mon application, il y a un tableau multidimensionnel avec potentiellement beaucoup de données, donc enregistrer complètement cet objet chaque fois que l'utilisateur change, il semble irréalisable. J'ai lu sur le modèle de commande et finalement trouvé l'article this mais je ne le comprends pas tout à fait. Je ne suis pas sûr de la façon dont son exemple de code fonctionne et si cela fonctionnera ou non dans mon application. De plus, cette "nouvelle" méthode est-elle préférable au modèle GoF? Mon application a des outils comme un outil de pinceau et de remplissage qui fonctionne sur le document actuel et je ne suis pas vraiment sûr de la meilleure façon d'implémenter les fonctions annuler/rétablir, mais je sais que l'enregistrement de l'état de chaque opération ne permettrait pas pour infini défaire et refaire qui est ce que je suis après. Je ne suis pas sûr si le modèle de commande peut être utilisé dans ce contexte ou si et non comment et comment l'implémentation de l'article fonctionne.Essayer d'implémenter Undo/Redo et trouvé cet article que je ne comprends pas très bien. Aidez-moi?

Espérons que quelqu'un puisse élaborer sur l'article ou peut-être expliquer comment le modèle de commande pourrait être adapté à mes besoins. Merci d'avoir lu!

Répondre

1

Créez une classe avec trois valeurs (location, oldvalue et newvalue, où l'emplacement pointe vers un élément de votre tableau multidimensionnel) et deux méthodes (undo, redo). Lors de chaque opération, créez un tableau de ces objets pour chaque élément de votre grand tableau qui change, et poussez-le sur une pile d'annulation. Lorsque vous quittez la pile d'annulation, appelez Annuler, puis poussez vers une pile de rétablissement. Opposé pour refaire pop. Rappelez-vous juste d'effacer la pile de rétablissement avec de nouvelles actions.

EDIT:

Exemple:

public void undo() 
{ 
    location = oldvalue; 
} 

public void redo() 
{ 
    location = newvalue; 
} 

Et puis un exemple des piles:

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

Si simple! Merci beaucoup! –

1

Juste faire un peu de recherche me conduire à quelques solutions possibles. Le plus simple utilise probablement une pile. Un autre utilise le motif memento. Mais vous puisque vous avez demandé à propos du modèle de commande ici est un exemple simple.

Ceci est essentiellement tiré de l'exemple de 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(); 
    } 
} 

Utilisation du modèle de commande.

Nous faisons deux "actions" à l'instance de documentinvoker (en implémentant notre modèle de commande).

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

maintenant nous pouvons annuler ces actions.

instance.Undo(1); 

Le texte dans le document sera maintenant.

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

maintenant nous pouvons refaire cette action

instance.Redo(1); 

Le texte sera.

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

Évidemment, vous devrez modifier cela pour répondre à vos besoins. Et si vous voulez un peu plus d'explications, consultez l'article http://www.codeproject.com/KB/books/DesignPatterns.aspx.

Questions connexes