| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Unter einem Code Kata versteht man eine kleine, abgeschlossene Übung, mit der Softwareentwickler ihre Fertigkeiten trainieren können. Der Begriff stammt aus der asiatischen Kampfkunst. Ausführliche Informationen zu Code Katas finden sich hier.
Bei Design Patterns (deutsch Entwurfsmuster) handelt es sich laut Wikipedia um bewährte Lösungsschablonen für wiederkehrende Entwurfsprobleme in der Softwareentwicklung.
Literaturempfehlungen:
Ganz nach dem Motto "learning by doing" finden sich hier Code Katas für verschiedene gängige Design Patterns. Damit kann die Implementierung der Design Patterns in Java ganz praktisch geübt werden.
Ganz einfach:
Die Katas werden als Maven-Projekt zur Verfügung gestellt, das mit der "Maven-Projekt importieren"-Funktion (oder ähnlich lautend) in die jeweils bevorzugte IDE importiert werden kann.
| Software | Version |
|---|---|
| Java | Version 21 (oder höher) |
| Maven | 3.9.x (oder höher) |
| Git | (von GitHub unterstützte Version) |
Typ: Erzeugungsmuster (creational pattern)
Dieses Pattern wird verwendet, wenn eine Klasse den konkreten Typ der von ihr zu erzeugenden Objekte nicht kennen kann oder soll. Die Fabrikmethode liefert Objekte vom Typ eines Interfaces oder einer abstrakten Klasse zurück.
Damit wird eine lose Kopplung zwischen dem aufrufenden und den erzeugten Objekten erzielt.
Zudem hilft das Pattern bei der Umsetzung des Open/Closed-Prinzips (offen für Erweiterung, geschlossen für Änderung). Für die Erweiterung um eine zusätzliche Implementierung muss lediglich eine neue Klasse erstellt, sowie diese der Factory-Methode bekannt gemacht werden.
Package: de.doubleslash.kata.designpattern.factory
JUnit-Test: LoggerFactoryTest
In diesem Kata soll eine LoggerFactory implementiert werden, die je nach Konfiguration eine Unterschiedliche Logger-Klasse instanziert und zurückgeliefert werden.
UML
Die in der folgenden Tabelle gelisteten Logger-Klassen sollen erstellt werden. Um es einfach zu halten, soll deren Implementierung nicht in eine tatsächliche Datei oder Datenbank loggen. Stattdessen wird jeweils die Nachricht inklusive eines entsprechenden Suffix nach System.out geschrieben.
| Logger-Klasse | Konfiguration | Funktion | Bemerkung |
|---|---|---|---|
| FileLogger | file | Loggt in eine Datei | Schreibt nachricht + " (in eine Datei geloggt)" nach System.out. |
| DbLogger | db | Loggt in eine Datenbank | Schreibt nachricht + " (in eine DB geloggt)" nach System.out. |
| SilentLogger | silent | Macht gar nichts | Ignoriert die Nachricht und schreibt nichts nach System.out. |
Typ: Verhaltensmuster (behavioral pattern)
Das State Pattern ermöglicht es einem Objekt, sein Verhalten abhängig von seinem internen Zustand zu ändern. Statt in einer großen switch-Anweisung werden die verschiedenen Verhaltensweisen in unterschiedlichen Zustandsobjekten implementiert. Mit diesem Entwurfsmuster werden üblicherweise Zustandsautomaten realisiert.
In diesem Kata wird eine Spülmaschine modelliert. Je nachdem, welche Funktion an der Spülmaschine ausgeführt wird (z.B. einschalten, spülen, Tür öffnen), ändert die Spülmaschine ihren Zustand. Folgende Zustände und Funktionen sollen implementiert werden:
| Funktion | Bedeutung |
|---|---|
| turnOn() | einschalten |
| turnOff() | ausschalten |
| wash() | Spülvorgang starten |
| finished() | Spülvorgang zu Ende |
| openDoor() | Tür öffnen |
| closeDoor() | Tür schließen |
| Zustand | Bedeutung |
|---|---|
| Off | Ausgeschaltet |
| On | Eingeschaltet |
| Washing | Spült |
| Paused | Pausiert ( Tür wurde geöffnet) |
Initial befindet sich die Spülmaschine im Zustand "Off". Schaltet man sie mit der Funktion turnOn() ein, befindet sie sich im Zustand "On". Betätigt man dann die wash()-Funktion, wird sie in den Zustand "Washing" versetzt, u.s.w.
In diesem Kata werden nur die im Zustandsdiagramm dargestellten Zustandsübergänge realisiert. Ein neuer Zustand wird erreicht, wenn eine Funktion ausgeführt wird, die durch einen vom aktuellen Zustand wegführenden Pfeil dargestellt ist.
Beispiel: ist die Spülmaschine im Zustand "Washing", und die Funktion openDoor() wird ausgeführt, ändert sich der Zustand auf "Paused".
In allen anderen Fällen soll der Zustand der Maschine sich nicht ändern. Zum Beispiel: wenn die wash()-Funktion betätigt wird, während die Maschine sich im Zustand "Off" befindet, weil sie noch nicht eingeschaltet ist, bleibt die Maschine im Zustand "Off".
(In einer alternativen Vorgehensweise würde bei unerlaubten Statusübergängen eine IllegalArgumentException oder UnsupportedOperationException geworfen, damit etwaige Programmierfehler sofort sichtbar werden.)
UML
Unsere Spülmaschine wird von der Klasse Dishwasher repräsentiert. Ihren internen Zustand hält sie im Attibut dishwasherState.
Alle konkreten Zustände erweitern die abstrakte Klasse DishwasherState. Sie müssen mindestens die abstrakte Methode getStateName() überschreiben und den Namen ihres repräsentierten Zustands zurückgeben (z.B. "off", "on", ...).
Alternativ könnte DishwasherState als Interface realisiert werden. Hier wurde jedoch die abstakte Klasse gewählt, damit dort das Standardverhalten für nicht definierte Zustandsübergänge (keine Zustandsänderung) implementiert und an die konkreten Zustandsklassen vererbt werden kann.
In den Zustandsklassen werden nur die im Zustandsdiagramm definierten Zustandsänderungen durch Überschreiben der entsprechenden Funktions-Methoden implementiert (z.B. turnOn() in der Klasse OffState, die den Zutand "Off" modelliert). Die Zustandsklassen halten ihrerseits mit dem Attribut dishwasher eine Referenz auf die Spülmaschine. In der überschriebenen Funktions-Methode rufen sie dishwasher.setState(...) auf, um den neuen Zustand der Spülmaschine zu setzen.
Package: de.doubleslash.kata.designpattern.state
JUnit-Test: DishwasherTest
| Back | FazBrowse Home | New Git URL |