6.2. Softwarearchitektur und Entwurfsmuster
Erzeugungsmuster
Singelton
- Singleton stellt sicher, dass es kein zweites Objekt des selben Typs zum selben Zeitpunkt gibt und dass darauf ein zentraler Zugriff geboten wird.
- Vorteile:
- ein System nur eine Instanz eines Typs zu einem Zeitpunkt haben darf, und diese Instanz zentral zur Verfügung gestellt wird
- diese eine Instanz durch Ableitung erweiterbar und für Clients ohne Änderung verfügbar
- Besonderheit:
- Initialisierung der Instanz:
- early (sofort beim Start des Programmes => langsamer Programmstart)
- lazy (beim ersten Aufruf der Instanz)
- ↪ Übungsbeispiel
Abstract Factory
- abstrakte Schnittstelle für die Erzeugung von Objekten
- konkrete Erzeugung in Subklassen
- Rückgabetyp: Basistyp
- Vorteile:
- ein System will die konkreten Produkterzeugung nicht vorwegnehmen
- die Erben den konkreten Produkttyp bestimmen lassen will
- die Erzeugung an eine von mehreren Hilfsklassen (Abstract Factory) delegiert wird und diese Delegation an einer Stelle konzentriert werden soll
- ↪ Übungsbeispiel
Prototype
- sehr flexible Objekterzeugung
- Je unterstütztem Typ wird ein Exemplar zur Verfügung gestellt, um neue Objekte als Kopie dieses Exemplars zu erzeugen
- Properties-File halten die absoluten Klassennamen
- ↪ Übungsbeispiel
Strukturmuster
Bridge
- Entkopplung zwischen Abstraktion und Implementierung
- Client hat nur Zugriff auf das Bridge-Objekt und dieses ruft das gekapselte Objekt unmittelbar mit identen Parametern auf
- Es wird weder die Schnittstelle angepasst (Adapter) noch werden zusätzliche Operationen ausgeführt (Proxy).
- ↪ Übungsbeispiel
Proxy
- kompatiblen Stellvertreter für ein dahinter verborgenes Objekt
- Zugriffe auf das verborgene Objekt erfolgen indirekt über den Proxy
- Vorteile:
- ein entferntes Objekt in einem anderen Adressraum soll aufgerufen werden
- die aufwändige Erzeugung eines Objekts bis zur Verwendung soll verzögert werden
- die Berechtigung vor dem Zugriff auf ein schützenswertes Objekt soll geprüft werden
- ↪ Übungsbeispiel
Adapter
- Adapter stellt ein – evtl. vorhandenes - Interface in einem anderem, davon abweichenden Interface zur Verfügung, sodass eine nahtlose Einbindung in einen inkompatiblen Client möglich wird.
- In Umgebungen mit Einfachvererbung geschieht dies durch Delegation an ein referenziertes Objekt (Adaptee) des zu integrierenden Typs.
- Beispiel: TextView (UI-Element) kann als StringBuffer betrachtet werden.
- Vorteile:
- zwei oder mehr inkompatible Typen interagieren
- bestehende inkompatible Funktionalität soll anderweitig genutzt werden
- ↪ Übungsbeispiel
Composite
- Bildet die Über-/Unterordnung in einem Baum von Komponenten ab
- Komponenten können Komponenten enthalten
- gemeinsame Basisklasse für Container und elementare Komponenten
- Vorteile:
- Darstellung von Teil-Ganzes-Beziehungen
- Gleichförmige Nutzbarkeit von Komponenten und Container für Clients
- ↪ Übungsbeispiel
Klassendiagramm |
Objektdiagramm |
|
|
Verhaltensmuster
Chain of Responsibility
- Reduziert die Kopplung zwischen dem Sender einer Nachricht und dem/den Empfänger(n)
- Interessierte Empfänger werden in einer Liste verwaltet (
LinkedList
)
- Die Empfänger erhalten die Nachricht der Reihe nach bis ein Empfänger sie behandelt. Dahinter gelistete Empfänger werden daraufhin ignoriert. (Abbruchbedingung)
- Beispiel: Ereignisbehandlung in GUI
Observer
- Bei Zustandsänderung eines Objektes werden alle davon abhängigen Objekte automatisch informiert
- Verwendung einer Liste:
LinkedList
- Vorteile:
- Eine Abstraktion zwei Aspekte hat, wobei einer vom anderen abhängt => Wiederverwendung
- Eine Änderung in einem Objekt zu Folgen in möglicherweise vielen anderen Objekten führen soll, ohne die tatsächliche Anzahl genau zu kennen.
- Ein Objekt in der Lage sein soll, andere Objekte zu benachrichtigen, ohne diese genauer zu kennen und an diese eng gekoppelt zu sein.
State
- Ermöglicht einem Objekt, sein Verhalten während der Laufzeit zu verändern
- Änderung des internen Zustandes
- Beispiel: TCP-Verbindungen (aufgebaut, horchend, geschlossen)
- Allen Zuständen haben eine gemeinsame Schnittstelle. Die verschiedenen konkreten State-Klassen implementieren dieses Interface dem jeweiligen Zustand entsprechend.
- ↪ Übungsbeispiel
Strategy
- Kapselung von verschiedenen Algorithmen einer Familie
- Verwendung:
- viele verschiedene Klassen unterscheiden sich nur in ihrem Verhalten
- verschiedene Varianten eines Algorithmus werden benötigt
- ein Algorithmus benötigt viele bzw. komplexe Daten, die vor dem Client verborgen werden sollen
- eine (Kontext-)Klasse definiert viele verschiedene Verhalten und verwendet dafür viele bedingte Anweisungen (Verzweigungen)
- Beispiel: Suchverfahren
- Ein Interface für alle unterstützten Algorithmen
Command
- Abläufe werden in Objekten zusammengefasst
- Festgelegte Abläufe können in Sammlungen (Stack) zusammengefasst und verwaltet werden.
- Beispiel: Undo-Funktionalität
- ↪ Übungsbeispiel