Muster: State

Aus Wikibooks

Wechseln zu: Navigation, Suche

Inhaltsverzeichnis

[Bearbeiten] State / Zustand

Der Zustand (engl. State) wird verwendet, um Änderungen des Verhaltens eines Objekts abhängig von seinem Zustand zu ermöglichen. Auch bekannt als Objekte für Zustände (Objects for States).

[Bearbeiten] Verwendung

  • Das Verhalten eines Objekts ist abhängig von seinem Zustand.
  • Die übliche Implementierung soll vermieden werden, die Zustände eines Objekts und das davon abhängige Verhalten in einer großen Switch-Anweisung (basierend auf enumerierten Konstanten) zu kodieren. Jeder Fall der Switch-Anweisung soll in einer eigenen Klasse implementiert werden, so dass der Zustand des Objektes selbst wieder ein Objekt ist, das unabhängig von anderen Objekten ist.

[Bearbeiten] Problem

[Bearbeiten] Zustandsautomat

Für ein Objekt sind verschiedene Zustände, die möglichen Übergänge zwischen diesen Zuständen und das davon abhängige Verhalten zu definieren. Dies ist hier in Form eines endlichen Automaten dargestellt. Dabei zeigt der schwarze Kreis auf den Startzustand und der schwarze Kreis mit der weißen Umrandung auf den Endzustand. Die gerichteten Kanten (Pfeile) zwischen den Zuständen Closed, Open und Deleted definieren den Zustandswechsel.

[Bearbeiten] Hierarchische Zustandsautomat

Ein einzelner Zustand eines Objektes kann wiederum in eine Anzahl verschiedener Zustände aufgeteilt werden. Den Zustand Open kann man beispielsweise unterteilen in Read und Wrote. Sie bilden einen zusammengesetzten Zustand Open. Closed sowie Deleted betrachtet man unabhängig vom zusammengesetzten Zustand Open. Diese Zustände kann man in einer Hierarchie anordnen. Open, Closed und Deleted sind in der ersten Ebene. In der zweiten Ebene befinden sich Read und Wrote, die dem Zustand Open zugeordnet sind.

[Bearbeiten] Lösung

[Bearbeiten] Einfache Zustände

Das zustandsabhängige Verhalten des Objekts wird in separate Klassen ausgelagert, wobei für jeden möglichen Zustand eine eigene Klasse eingeführt wird, die das Verhalten des Objekts in diesem Zustand definiert. Damit das ursprüngliche Objekt die separaten Zustandsklassen einheitlich behandeln kann, wird eine gemeinsame Abstrahierung dieser Klassen definiert. Bei einem Zustandsübergang tauscht das ursprüngliche Objekt das von ihm verwendete Zustandsobjekt aus.

[Bearbeiten] Implementierung

Für das Ausprogrammieren des Zustandsmusters sollte vorher überlegt werden, ob

  • der Kontext die Zustände als Attribute hält.
  • bei jedem Zustandswechsel der vorherige Zustand gelöscht und ein neuer Zustand instantiiert wird, was zwar rechentechnisch aufwendiger aber sauberer für den Programmablauf ist. D.h., dass alle Membervariablen eines jeden Zustands gelöscht werden und ein evtl. späteres Debuggen von Anfang an ausgeschlossen wird. Man kann dann auch diesen Zustand mehrmals in ähnlichen Kontexten verwenden. (z.B. Zwei Dateien können in einem Dateisystem zur gleichen Zeit geöffnet sein. Dabei befinden sich jeweils die Dateien im Zustand: Open. Vom Open-Zustand existieren daher zwei Instanzen, jeweils eine Instanz für eine Datei.)
  • jeder Zustand nur einmal erzeugt wird - dann wenn er zum ersten Mal gebraucht wird - und daher alle möglichen Zustände parallel im Speicher existieren (hier wird das Singleton-Erzeugermuster verwendet).

[Bearbeiten] Akteure

  • Kontext
    • Definiert die klientseitige Schnittstelle.
    • Verwaltet die separaten Zustandsklassen und tauscht diese bei einem Zustandsübergang aus.
  • Zustand
    • Definiert eine einheitliche Schnittstelle aller Zustandsobjekte.
    • Implementiert gegebenenfalls ein Standardverhalten. Beispielsweise kann im Zustand die Ausführung jeglichen Verhaltens gesperrt werden. Das Verhalten kann in diesem Falle nur dann ausgeführt werden, wenn es vom konkreten Zustand durch Überschreiben der entsprechenden Methode freigeschaltet wurde.
  • Konkreter Zustand
    • Implementiert das Verhalten, das mit dem Zustand des Kontextobjekts verbunden ist.

[Bearbeiten] Vorteile

  • Komplexe und schwer leserliche Bedingungsanweisungen können vermieden werden.
  • Neue Zustände und neues Verhalten können auf einfache Weise hinzugefügt werden. Die Wartbarkeit wird erhöht.
  • Zustandobjekte können wiederverwendet werden.

[Bearbeiten] Nachteile

  • Bei sehr einfachem zustandsbehaftetem Verhalten rechtfertigt unter Umständen der Implementierungsaufwand nicht den Nutzen.

[Bearbeiten] Beispiele

Prinzipiell kann jedes zustandsabhängige Verhalten durch dieses Entwurfsmuster abgebildet werden. Einige Beispiele für zustandsbehaftete Problemstellungen sind

  • Verwaltung von Sessions
  • Verwaltung von Ein- und Ausgabeströmen
  • Zustandbehaftete Bedienelemente einer grafischen Benutzeroberfläche
  • Parkautomaten
Persönliche Werkzeuge