Buchgenerator (deaktivieren)

Muster: Command

Aus Wikibooks

Wechseln zu: Navigation, Suche

Das Kommando oder der Befehl (engl. Command) ist ein Verhaltensmuster (Behavioral Patterns). Es dient zum Kapseln von Anfragen als Kommando-Objekte, um damit Empfänger zu parametrisieren. Anfragen können dabei in Warteschlangen gestellt, aufgezeichnet und später ggf. auch wieder rückgängig gemacht werden.

Auch bekannt als: Aktion, Transaktion (Action, Transaction)


[Bearbeiten] Verwendung

  • Objekte sollen mit einer auszuführenden Aktion, dem Befehl, parametrisiert werden. Das ist die objektoriertierte Entsprechung zu Rückruffunktionen (eng. callback function).
(z.B. eine Schaltfläche in einer GUI soll mit einer Aktion verknüpft werden)
  • Befehle, also auszuführende Aktionen, werden in einzelne Objekte gekapselt. Dies folgt dem objektorientierten Prinzip der Kapselung des Veränderbaren.
  • Das Erstellen des Befehls und das tatsächliche Ausführen finden zu verschiedenen Zeiten oder in einem anderen Kontext (Thread, Prozess, Rechner) statt.
  • Da Befehle in Objekten gekapselt sind, können sie gespeichert, herumgereicht, gruppiert oder modifiziert werden. Dies erlaubt eine Reihe von interessanten Anwendungsmöglichkeiten, z.B.
    • Implementation eines Rückgängig-Mechanismus (Undo). Bei jeder Ausführung werden die zur Umkehrung nötigen Daten im Befehls-Objekt gespeichert und das Objekt selber auf einem Stapel gesichert. Um das Gegenteil Wiederherstellen (Redo) zu implementieren, genügt ein zweiter Stapel für die rückgängig gemachten Befehle.
    • Implementation einer Warteschlange, bei der die Befehle nacheinander abgearbeitet werden. Dabei sind die Befehle lose an die ausführende Einheit gekoppelt, so dass ein Austauschen, Ändern etc. zur Laufzeit möglich ist.
    • Implementation von Logging von Befehlen und einer Wiederherstellung nach einem Systemabsturz.
    • Gruppierung von mehreren Befehlsobjekten in einem Makrobefehl, um verschiedene Aktivitäten gebündelt auszuführen.

[Bearbeiten] UML-Diagramm

Klassendiagramm
Klassendiagramm

[Bearbeiten] Akteure

  • Befehl
    • Basisklasse aller Befehle
    • definiert die Schnittstelle zum Ausführen des Befehls
  • Konkreter Befehl
    • speichert den zum Ausführen nötigen Zustand, darunter typischerweise auch einen Verweis auf den Empfänger
    • implementiert die Befehlsschnittstelle
  • Klient
    • erzeugt einen konkreten Befehl und versieht ihn mit einem Verweis auf den Empfänger und allen anderen nötigen Informationen
    • gibt dem Aufrufer eine Referenz auf den konkreten Befehl
  • Aufrufer
    • besitzt einen oder mehrere Verweise auf Befehle
    • fordert diese Befehle bei Bedarf auf, ihre Aktion auszuführen
  • Empfänger
    • Der konkrete Befehl ruft Methoden des Empfängerobjektes auf, um seine Aktion auszuführen.
    • An den Empfänger werden keine besonderen Anforderungen gestellt. Er muss nichts über die anderen Akteure wissen. Somit kann jede Klasse als Empfänger dienen.

[Bearbeiten] Vorteile

  • Auslösender und Ausführender sind entkoppelt.
  • Ausführenden können zur Laufzeit dynamisch neue Befehle übergeben werden.
  • Befehlsobjekte können wie andere Objekte auch manipuliert werden (Verändern, Filtern, Zwischenspeichern, etc.).
  • Befehlsobjekte können zu komplexen Befehlen kombiniert werden (Makros, realisiert als Kompositum).

[Bearbeiten] Nachteile

  • Es wird für jedes Kommando eine neue Klasse benötigt. Dies kann sehr schnell zu einer großen Menge von Klassen führen.

[Bearbeiten] Beispiel

Ein gutes Beispiel für das Befehlsmuster, ist die Verknüpfung von GUI-Elementen, wie Schaltflächen oder Menüpunkten, mit den entsprechenden Aktionen:

  • Konkrete Befehle realisieren dann Aktionen wie Datei öffnen, Rückgängig oder Schreibmarke nach rechts
  • Klienten sind die Applikation oder Dialoge.
  • Aufrufer sind Schaltflächen, Menüpunkte oder Hotkeys.
  • Empfänger sind die Applikation (Datei öffnen) oder das Dokument (Rückgängig, Einfügemarke nach rechts)

[Bearbeiten] Ideen hinter erweiterten Anwendungen

  • Der Makro-Befehl:
    • Ein Makro-Befehl gruppiert einen Menge von Aktionen und führt sie gemeinsam aus. Dabei sind die einzelnen Aktionen in den Befehlsobjekten gekapselt. Idee ist nun, in einem Makro-Befehlsobjekt mehrere Befehlsobjekte zu speichern und diesen in einer vorgegebenen Reihenfolge zu befehlen, die Aktionen auf dem ihnen zugeordnetem Empfängerobjekt auszuführen.
    • Der Makro-Befehl implementiert ebenfalls die Schnittstelle "Abstrakter Befehl". Ergänzt wird der Makro-Befehl um eine Liste oder ein Array zur Speicherung einer Reihe von Befehlsobjekten. Bei der Initialisierung (oder später dynamisch zur Laufzeit) wird dem Makro-Befehl ein Array von Befehlsobjekten übergeben.
    • In der Methode ausführen(), welche einen Befehl zu Abarbeitung der Aktionen bewegt, iteriert der Makro-Befehl durch das Befehlsarray und ruft für jedes der Befehlsobjekte die Methode ausführen() auf.
    • Eine Rückgängig-Funktionalität kann auch hier einfach gewährleistet werden, indem der Makro-Befehl rückwärts durch das Befehlsarray iteriert und auf jedem gespeichertem Befehlsobjekt die rückgängig()-Methode aufruft, die den Zustand des Systems vor der letzten Ausführung der ausführen()-Methode wiederherstellt.

[Bearbeiten] Verwandte Entwurfsmuster

  • Makro-Befehle können als Kompositum implementiert werden.
  • Das Memento-Entwurfsmuster kann die Objektzustände speichern, um eine Rückgängigfunktion zu vereinfachen.
Persönliche Werkzeuge