Frage

Ich habe einige der Forschung bereits getan, wie ich den Titel dieser Frage erreichen können. Die App an dem ich arbeite seit ein paar Jahren in der Entwicklung oder so (langsame Fortschritte aber, Sie alle wissen, wie es in der realen Welt ist). Es ist jetzt eine Anforderung für mich in Undo / Redo mehrere Level-Funktionalität zu setzen. Es ist ein bisschen spät, um zu sagen: „Sie darüber nachgedacht haben sollten, bevor Sie beginnen“ ... na ja, wir darüber dachten - und wir haben nichts davon, und jetzt ist es hier. Von der Suche um SO (und externe Links) Ich kann sehen, dass die beiden am häufigsten verwendeten Methoden ...

zu sein scheinen

Command-Muster

Memento Pattern

Der Befehl Muster sieht aus wie es ist ein verdammt viel Arbeit sein würde, kann ich nur vorstellen, dass es auch Tausende von Bugs in den Prozess zu werfen, damit ich Lust haben nicht wirklich ein.

Das Memento Muster ist eigentlich viel wie das, was ich für das in meinem Kopf hatte. Ich dachte, wenn es eine Möglichkeit ist schnell einen Schnappschuss des Objektmodelles im Speicher zur Zeit nehmen, dann würde ich in der Lage sein, es irgendwo zu speichern (vielleicht auch in Erinnerung, vielleicht in einer Datei). Es scheint wie eine gute Idee, das einzige Problem, das ich für diese sehen kann, ist, wie es mit integrieren wird, was wir bereits geschrieben haben. Sie sehen die App, wie wir es zeichnet Bilder in einem großen Panel (möglicherweise Hunderte) haben und erlaubt dann den Benutzer sie entweder über die Benutzeroberfläche oder über einen speziell angefertigten Eigenschaften Raster zu manipulieren. Die gesamte Anwendung ist mit einem großen Beobachter-Muster verknüpft. Die zweite etwas ändert, werden Ereignisse gefeuert und alles, was Bedürfnisse Update tut. Das ist schön, aber ich kann nicht umhin zu denken, dass, wenn ein Benutzer Text in ein texfield auf dem Eigenschaftenraster eintritt, wird es ein wenig dauern, bis die UI einholt (scheint, als jedes Mal der Benutzer eine Taste drückt, wird ein neuer Snapshot hinzugefügt werden auf die Undo-Liste). Also meine Frage an Sie ist ....

  • Möchten Sie wissen, dass gute Alternativen zum Memento Muster, das könnte funktionieren.
  • Denken Sie, das Memento-Muster in hier passen oder wird es die App nach unten zu viel langsamer.
  • Wenn das Memento-Muster ist der Weg zu gehen, was die effizienteste Art und Weise ist eine Momentaufnahme des Objektmodells zu machen (i denken war es oder etwas Serialisierung)
  • Sollte die Snapshots gespeichert werden oder ist es möglich, sie in Dateien zu setzen?

Wenn Sie so weit gekommen sind, danke herzlich für das Lesen. Jede Eingabe Sie wird wertvolle und sehr geschätzt.

War es hilfreich?

Lösung

Die kritischen Dinge für Undo / Redo sind

  • zu wissen, in welchem ??Zustand Sie müssen zum Speichern und Wiederherstellen
  • zu wissen, wann Sie brauchen, um den Zustand speichern

Undo Hinzufügen / Redo nach der Tat ist immer eine schmerzhafte Sache zu tun - (Ich weiß, dass dieser Kommentar ist von keinerlei Nutzen für Sie jetzt, aber es ist immer am beste Unterstützung in das Anwendungs-Framework zu entwerfen, bevor Sie beginnen, wie es Menschen hilft Verwendung Undo freundliche Muster während der Entwicklung).

Möglicherweise ist der einfachste Ansatz wird ein Memento-basierte sein:

  • alle die Daten liegen, die Ihre „Dokument“ bildet. Können Sie diese Daten in irgendeiner Art und Weise vereinen, so dass es ein kohärentes Ganzes bildet? Normalerweise, wenn Sie Ihre Dokumentstruktur in eine Datei serialisieren können, ist die Logik, die Sie brauchen, ist in dem Serialisierung-System, so dass gibt Ihnen eine Art und Weise an. Die Kehrseite mit diesem direkt in der Regel ist, dass Sie in der Regel zu serialise allem haben so Ihre undo wird sehr groß und langsam sein. Wenn möglich, Refactoring Code, so (a) eine gemeinsame Serialisierung Schnittstelle in der gesamten Anwendung (so dass jeder einzelne Teil Ihrer Daten gespeichert / wiederhergestellt werden können einen allgemeinen Aufruf verwendet wird) verwendet wird, und (b) jedes Untersystem ist gekapselt so dass Änderungen an den Daten über eine gemeinsame Schnittstelle gehen (und nicht viele Menschen, die direkt Membervariablen ändern, sollten sie alle eine API durch das Objekt auf Anfrage zur Verfügung gestellt rufen, dass es Änderungen an sich selbst macht) jedes Sub- und (c) Teil der Daten hält eine „Versionsnummer“. Jedes Mal, wenn eine Änderung (durch die Schnittstelle in (b)) hergestellt wird, soll es diese Versionsnummer erhöht. Dieser Ansatz bedeutet, Sie können nun Ihre gesamte Dokument scannen und die Versionsnummern verwenden nur die Teile davon zu finden, die seit dem letzten sah geändert haben, und dann die minimale Menge serialise, um den geänderten Zustand gespeichert und wiederhergestellt werden.

    • Geben Sie einen Mechanismus, bei dem ein einzelner Undo-Schritt aufgezeichnet werden kann. Diese Einrichtung ermöglicht multple Systeme, um Änderungen an der Datenstruktur, und dann, wenn alles aktualisiert wurde, das Auslösen einer Undo-Aufzeichnung. Arbeiten, wenn dies zu tun schwierig sein kann, aber es kann in der Regel durch das Scannen Ihres Dokuments für Änderungen (siehe oben) in der Nachrichtenschleife erreicht werden, wenn die UI Verarbeitung jedes Eingabeereignisses beendet ist.

Darüber hinaus würde ich für einen Befehl basierten Ansatz raten gehen, denn es gibt viele Vorteile, um es neben Undo / Redo ist.

Andere Tipps

Nun, hier ist mein Gedanke auf dieses Problem.

1- Sie müssen Multi-Level-Undo / Redo-Funktionalität. so dass Sie zum Speichern von Benutzeraktionen müssen durchgeführt, die in einem Stapel gespeichert werden kann.

2- Ihr zweites Problem, wie zu erkennen, was durch eine Operation geändert wurde ich denke, durch Memento-Muster, ist es eine ziemliche Herausforderung. Memento dreht sich alles um chungsAnfangs Objektstati im Speicher.

entweder, müssen Sie speichern, was durch eine Operation geändert wird, so dass Sie diese Informationen verwenden können, die opertions rückgängig zu machen.

Befehlsmuster für die Undo / Redo-Funktionalität entwickelt, und ich würde sagen, dass sein Ende aber es lohnt sich, während das Design zu implementieren, die seit mehreren Jahren verwendet wird, und arbeitet für die meisten Anwendungen.

Wenn die Leistung erlaubt es könnten Sie Ihre Domain vor jeder Aktion serialisiert. Ein paar hundert Objekte ist nicht viel, wenn die Objekte selbst nicht groß sind.

Da Ihr Objektgraph wahrscheinlich nicht trivial ist (das heißt Verwendungen Vererbung, Zyklen, ...) die integrierte XmlSerializer und JsonSerializers sind ausgeschlossen. Json.net unterstützt diese, aber hat einige verlustbehafteten Conversions auf einigen Arten (lokale Datetime, Zahlen, ...), so ist es zu schlecht.

Ich denke, die protobuf Serializer müssen entweder irgendeine Form von DTD (Proto-Datei) oder Dekoration aller Eigenschaften mit Attributen Abbildung ihren Namen zu einer Reihe, so dass es nicht optimal sein könnte.

BinaryFormatter können die meisten Sachen Serialisierung, Sie müssen nur alle Klassen mit dem Attribut [Serializable] dekorieren. Aber ich habe es selbst nicht verwendet, so könnte es Gefahren, die ich bin mir nicht bewusst. Vielleicht im Zusammenhang mit Singletons oder Ereignissen.

Sie können den Überwachte Undo-Framework finden, nützlich zu sein. http://muf.codeplex.com/

Es nutzt etwas Ähnliches wie die Erinnerungsmuster, indem er für Änderungen überwachen, wie sie geschehen und ermöglicht es Ihnen, die Delegierten auf den Rückgängig-Stapel zu setzen, die die Änderung umkehren / Redo.

Ich hielt einen Ansatz, der das Dokument würde serialisiert / deserialisiert wurde aber über den Overhead betroffen. Stattdessen überwache ich für Änderungen im Modell (oder View-Modell) auf einem Grundstück von Immobilien Basen. Dann, je nach Bedarf, verwende ich die MUF-Bibliothek „Batch“ damit verbundene Veränderungen, so dass sie Undo / Redo als Einheit zu ändern.

Die Tatsache, dass Sie Ihre UI Setup auf Änderungen des zugrunde liegenden Modells zu reagieren ist gut. Es klingt wie Sie es die Undo / Redo-Logik injizieren könnte und die Änderungen würden Blase an den UI-up.

Ich glaube nicht, dass Sie viel Verzögerung oder Leistungseinbußen sehen würde. Ich habe eine ähnliche Anwendung, mit einem Diagramm, dass wir auf der Grundlage der Daten im Modell machen. Wir haben mit diesem bisher gute Ergebnisse hatte.

Sie können weitere Informationen und Dokumentation auf der Codeplex-Website finden Sie unter http://muf.codeplex.com/. Die Bibliothek ist auch über NuGet, mit Unterstützung für .NET 3.5, 4.0, SL4 und WP7.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top