Entwurfsmuster und Frameworks Zustand (State)
Tobias Rafreider Tobias.Rafreider@htwg-konstanz.de Hochschule Konstanz Technik, Wirtschaft und Gestaltung
University of Applied Sciences
Einordnung
• Klassifikation:
– Ein Objektbasiertes Verhaltensmuster
• Zweck:
– Ermögliche es einem Objekt sein Verhalten zu ändern, wenn sein interner Zustand sich ändert. Es wird so aussehen, als ob ein
Objekt seine Klasse gewechselt hat.
• Auch bekannt als:
– Objekte als Zustände
Motivation: Zustände von Dateien
• Die Klasse File verwaltet ein Zustandsobjekt von FileState
– Konkret: Ein Exemplar einer Unterklasse von FileState
• Ändert sich der Zustand der Verbindung, so ändert das
state.open();
Anwendbar wenn …
• das Verhalten eines Objekts von seinem Zustand abhängt.
– Zustand und damit das Verhalten ändert sich dynamisch zur Laufzeit.
• die Operationen einer Klasse große mehrteilige Bedingungsanweisungen enthalten.
– Es existiert eine Klassenvariable für den Zustand
– Methoden sind stark „verschachtelt“, d.h. es gibt viele IF-Anweisungen für die Zustände.
!Jeder Zweig der Bedingungsanweisung wird in eine separate Klasse ausgelagert.
Allgemeine Struktur
• Kontext
– Definiert die für den Klienten interessierende Schnittstelle – Verwaltet ein Exemplar eines konkreten Zustandsobjekts
• (Abstrakter) Zustand
– Definiert die Schnittstelle für die zu implementierenden Zustände – Default-Implementierungen sind möglich
• Konkrete Zustands-Unterklassen
…
Interaktionen
• Das Kontextobjekt delegiert zustandsspezifische Anfragen an das aktuelle konkrete Zustandsobjekt.
• Ein Kontext kann sich selbst als ein Argument an das bearbeitende Zustandsobjekt mitgeben
– Nötig, falls Zustandsobjekte das Kontextobjekt benötigen – Falls Operationen von Zustandsobjekten in neue Zustände
überführen.
• Das Kontextobjekt bietet die für den Klienten interessante Schnittstelle.
– Klienten können zu beginn das Kontextobjekt mit einem Zustand konfigurieren
– Direkter Zugriff auf die Zustandsobjekte nicht mehr nötig.
– Kontextobjekte können entscheiden, welche Zustände aufeinander
Konsequenzen
• Mit der Anzahl der Zustände wächst die Anzahl der Klassen linear, aber…
– alles in einer Klasse zu kodieren erfordert viele Kontrollstrukturen (z.B. für jeden Zustand einen IF-Block oder SWITCH-Block)
• Code weniger explizit
• Schwieriger zu verändern, zu warten und zu erweitern
Beispiel Code (1)
• Annahme
– Gehen Sie davon aus, dass im Folgenden die Implementier- ungen für die konkreten
Zustände bereits existieren.
! Implementierung des Zustands
„Closed“ nächste Folie.
public abstract class FileState {
public abstract void open(File context);
public abstract void close(File context);
public abstract void delete(File context);
} //Konkrete Klasse
public class File {
private FileState file_state = null;
private String filename = null;
public File(String filename){
this.filename = filename;
//setze Zustand auf closed
file_state = new ClosedState();
}
public void open(){
file_state.open(this);
}
public void close(){
file_state.close(this);
}
public void delete(){
file_state.delete(this);
}
public void setStatus(FileState state){
this.file_state = state;
} }
Beispiel Code (2)
public class ClosedState extends FileState {
@Override
public void close(File context) {
System.out.println("Schließen nicht möglich im Zustand 'schließen'");
}
@Override
public void delete(File context) {
context.setStatus(new DeletedState());
System.out.println("Datei im Zustand gelöscht");
}
@Override
public void open(File context) {
context.setStatus(new OpenState());
System.out.println("Datei im Zustand geöffnet");
Das Statusobjekt wir an dieser Stelle im Kontextobjekt ausgetauscht.
Abschließende Bewerkungen
• Bekannte Verwendung:
– TCP-Verbinungsprotokolle – Grafikprogramme
• Paletten als Zustände
• Verwandt mit Fliegengewicht
– Falls die Zustandsobjekte gemeinsam genutzt werden
– Solche Fliegengewichte haben allerdings keinen intrinsischen Zustand.