Skip to content

Commit 90d9cd2

Browse files
author
swaldmann
committed
Added description for State pattern.
1 parent e534dc3 commit 90d9cd2

1 file changed

Lines changed: 74 additions & 3 deletions

File tree

README.md

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ Damit kann die Implementierung der Design Patterns in Java ganz praktisch geübt
3030

3131
Ganz einfach:
3232
* Für jedes Design Pattern gibt es ein entsprechendes Package mit vorgefertigten Klassengerüsten, sowie einen JUnit-Test.
33-
* Die TODOs in den Gerüst-Klassen müssen durch Implementierung des jeweiligen Design Patterns so erledigt werden,
34-
dass alle JUnit-Tests erfolgreich durchlaufen.
33+
* Die TODOs in den Gerüst-Klassen werden durch Implementierung des jeweiligen Design Patterns so erledigt,
34+
dass alle JUnit-Tests erfolgreich durchlaufen. Die Testklassen selbst sollen dabei **_nicht_** geändert werden.
3535

3636
## Voraussetzungen ##
3737

@@ -63,7 +63,7 @@ Logger-Klasse instanziert und zurückgeliefert werden.
6363

6464
**UML**
6565

66-
![alt](doc/images/factory_method.png)
66+
![UML: Klassendiagramm Factory Method](doc/images/factory_method.png)
6767

6868
Die in der folgenden Tabelle gelisteten Logger-Klassen sollen erstellt werden. Um es einfach zu halten, soll deren
6969
Implementierung nicht in eine tatsächliche Datei oder Datenbank loggen. Stattdessen wird jeweils die Nachricht
@@ -74,3 +74,74 @@ inklusive eines entsprechenden Suffix nach `System.out` geschrieben.
7474
| FileLogger | file | Loggt in eine Datei | Schreibt `nachricht + " (in eine Datei geloggt)"` nach `System.out`. |
7575
| DbLogger | db | Loggt in eine Datenbank | Schreibt `nachricht + " (in eine DB geloggt)"` nach `System.out`. |
7676
| SilentLogger | silent | Macht gar nichts | Ignoriert die Nachricht und schreibt nichts nach `System.out`. |
77+
78+
### State (Zustand) ###
79+
80+
**Typ**: Verhaltensmuster (_behavioral pattern_)
81+
82+
Das State Pattern ermöglicht es einem Objekt, sein Verhalten abhängig von seinem internen Zustand zu ändern. Statt in
83+
einer großen switch-Anweisung werden die verschiedenen Verhaltensweisen in unterschiedlichen Zustandsobjekten
84+
implementiert. Mit diesem Entwurfsmuster werden üblicherweise
85+
[Zustandsautomaten](https://de.wikipedia.org/w/index.php?title=Zustandsautomat_(UML)) realisiert.
86+
87+
### State Pattern Kata ###
88+
89+
In diesem Kata wird eine Spülmaschine modelliert. Je nachdem, welche Funktion an der Spülmaschine ausgeführt wird
90+
(z.B. einschalten, spülen, Tür öffnen), ändert die Spülmaschine ihren Zustand. Folgende Zustände und Funktionen
91+
sollen implementiert werden:
92+
93+
![UML: Zustandsautomat Spülmaschine](doc/images/state_transitions.png)
94+
95+
| Zustand | Bedeutung |
96+
|---------|--------------------------------|
97+
| Off | Ausgeschaltet |
98+
| On | Eingeschaltet |
99+
| Washing | Spült |
100+
| Paused | Pausiert ( Tür wurde geöffnet) |
101+
102+
| Funktion | Bedeutung |
103+
|-------------|--------------------------------|
104+
| turnOn() | einschalten |
105+
| turnOff() | ausschalten |
106+
| wash() | Spülvorgang starten |
107+
| finished() | Spülvorgang zu Ende |
108+
| openDoor() | Tür öffnen |
109+
| closeDoor() | Tür schließen |
110+
111+
Initial befindet sich die Spülmaschine im Zustand "Off". Schaltet man sie mit der Funktion `turnOn()` ein, befindet sie sich
112+
im Zustand "On". Betätigt man dann die `wash()`-Funktion, wird sie in den Zustand "Washing" versetzt.
113+
114+
In diesem Kata werden nur die im Zustandsdiagramm dargestellten Zustandsübergänge realisiert. Ein neuer Zustand wird
115+
erreicht, wenn eine Funktion ausgeführt wird, die durch einen vom aktuellen Zustand wegführenden Pfeil dargestellt ist.
116+
Beispiel: ist die Spülmaschine im Zustand "Washing", und die Funktion `openDoor()` wird ausgeführt, ändert sich der
117+
Zustand auf "Paused".
118+
119+
In allen anderen Fällen soll sich der Zustand der Maschine nicht ändern. Zum Beispiel: wenn die `wash()`-Funktion
120+
betätigt wird, während die Maschine sich im Zustand "Off" befindet, weil sie noch nicht eingeschaltet ist,
121+
bleibt die Maschine im Zustand "Off".
122+
123+
_(In einer alternativen Vorgehensweise würde bei unerlaubten Statusübergängen eine `IllegalArgumentException`
124+
oder `UnsupportedOperationException` geworfen, damit etwaige Programmierfehler sofort sichtbar werden.)_
125+
126+
**UML**
127+
128+
![UML: Klassendiagramm State Pattern](doc/images/state_class.png)
129+
130+
Unsere Spülmaschine wird von der Klasse `Dishwasher` repräsentiert. Ihren internen Zustand hält sie im Attibut
131+
`dishwasherState`.
132+
133+
Alle konkreten Zustände erweitern die abstrakte Klasse `DishwasherState`. Sie müssen mindestens die abstrakte Methode
134+
`getStateName()` überschreiben und den Namen ihres repräsentierten Zustands zurückgeben (z.B. "off", "on", ...).
135+
136+
Alternativ könnte `DishwasherState` als Interface realisiert werden. Hier wurde jedoch die abstakte Klasse gewählt,
137+
damit dort das Standardverhalten für nicht definierte Zustandsübergänge implementiert und an die konkreten Zustandsklassen
138+
vererbt werden kann.
139+
140+
In den Zustandsklassen werden nur die im Zustandsdiagramm definierten Zustandsänderungen durch Überschreiben der
141+
entsprechenden Funktions-Methoden implementiert (z.B. `turnOn()` in der Klasse `OffState`, die den Zutand "Off"
142+
modelliert). Die Zustandsklassen halten ihrerseits mit dem Attribut `dishwasher` eine Referenz auf die Spülmaschine.
143+
In der überschriebenen Funktions-Methode rufen sie `dishwasher.setState(...)` auf, um den neuen Zustand der
144+
Spülmaschine zu setzen.
145+
146+
**Package:** `de.doubleslash.kata.designpattern.state` \
147+
**JUnit-Test:** `DishwasherTest`

0 commit comments

Comments
 (0)