Forum: PC-Programmierung Undo/Redo-Konzept


von Dieter L. (Gast)


Lesenswert?

Hallo zusammen,

ich bin auf der Suche nach einem Ansatz/Konzept, wie man 
Undo/Redo-Funktionalität in eine PC-Software (bei mir C#) einbindet.

Kennt jemand eine schöne Webseite/Buch/Beschreibung wie man sowas 
allgemein löst? Auch gegenüber Stichwörtern bin ich aufgeschlossen.

Ganz prinzipiell habe ich mir davon schon eine Vorstellung gebildet. So 
ganz im Stile von einem Stack, der mit Aktionen/Methoden 
(UndoAction/RedoAction) beladen wird und die dann der Reihe nach vor und 
zurück ausgeführt werden. Wenn nur eine einzelne Art von Aktion 
rückgängig gemacht werden soll, dann ists ja trivial. Wenn aber 
verschiedenste Benutzeraktionen umkehrbar sein sollen, steige ich aus. 
:-)

Beispiel Zeichenprogramm: Immer nur die letzten Pinselstriche rückgängig 
machen ist mir noch klar. Wenn dann aber zwischendurch eine neue Ebene 
eingefügt wird, dann darauf gezeichnet wird, dann z.B. das Bild komplett 
gelöscht wird... das sind ja alles unterschiedlichste Aktionen, die auf 
ganz unterschiedliche Objekte/Datenstrukturen angewandt werden. Dennoch 
müssen diese auf eine Gemeinsamkeit (Schnittstelle?) heruntergebrochen 
werden können, die dann auf den Undo/Redo-Stack gelegt werden. Wie geht 
man da vor?

Danke.

von Chris .. (dechavue)


Lesenswert?

Hi,

Schau dir mal das Command Pattern von 
http://www.mycsharp.de/wbb2/thread.php?threadid=21273 an.

von Dieter L. (Gast)


Lesenswert?

Hallo Chris E.,

danke, das ist genau der Anstoss, den ich gesucht hatte. Prima.

von Stephan M. (stephanm)


Lesenswert?

Hi,

eine Alternative zum Command-Pattern bei Verwendung von MVC ist, die 
Events deines Models mit einer Undo/Redo-Schnittstelle auszustatten, 
siehe unten.

Je nach konkreter Aufgabenstellung kann eine Realisierung des 
Command-Patterns äußerst ekelhaft werden, da speziell bei komplexen 
Modellen die notwendigen Verknüpfungen zwischen Model und Command die 
"Separation of concerns"-Idee gegen die Wand fahren. Klar, man kann um 
alles herumprogrammieren aber irgendwann ists halt nicht mehr lustich.

Üblicherweise sendet ein Model ja Events an interessierte Parteien, um 
über Änderungen seiner Daten zu berichten. Die Events enthalten demnach 
in natürlicher Weise bereits die Daten eines atomaren Deltas, d.h. eine 
"Vorher-Nachher-Information". Man kann nun die Event-Klassen zusätzlich 
mit einer Undo/Redo-Funktion ausstatten - die Daten für die 
Undo/Redo-Schritte kapseln sie ja bereits, es fehlt also nur noch das 
Verhalten.

Das schöne an diesem Ansatz ist, dass das Model ja sowieso Herr über die 
generierten Events und damit auch Herr über die verwendete 
Implementierung der Event-Klassen ist. Ergo kann das "Redoable 
Event"-Pattern im Model-Bereich einfacher zu einer geschlossenen Einheit 
führen als dies gelegentlich mit dem Command-Pattern möglich ist, denn 
die Commands werden typischerweise ausserhalb des Models erzeugt.

Das Verfahren hat aber auch eine Reihe von Nachteilen, leider teilweise 
auch genau die, die man beim klassischen Command-Pattern auch hat.

Beispiel Speicherverbrauch: es laufen typischerweise viele "kleine" 
Events in der Undo/Redo-Queue auf. Mit einem Analogon der beim 
Command-Pattern gebräuchlichen "Command Compression" (Zusammenführen 
gleichartiger Commands zu einer Objektinstanz) lässt sich das aber 
möglicherweise gut in den Griff bekommen.

Liebe Grüße,

Stephan

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.