This flashcard is just one of a free flashcard set. See all flashcards!
56
Welche Entwurfsmuster gibt es?
Entwurfsmuster sind Lösungsschablonen für wiederkehrende Entwurfsprobleme im Grob- oder Feinentwurf. Sie lassen sich grob in erzeugende Muster, strukturelle Muster und Verhaltensmuster unterteilen. 23 dieser Patterns sind in Erich Gammas Buch Design Patterns - Elements of Reusable Object-Oriented Software beschrieben. Die Patterns heißen auch Gang of Four Patterns, bezugnehmend auf Gamma und seine 3 Coautoren. Hier eine kleine Auswahl der wichtigsten Patterns:
Singleton
Es soll nur ein Objekt einer Klasse erstellt werden können. Dazu wird einfach in der Methode instanceOf() überprüft, ob schon ein Objekt der Klasse exisitiert. Wenn ja, wird das alte Objekt zurückgeliefert, wenn nein, wird das neue Objekt erstellt.
Strategy
Verwandte Klassen unterscheiden sich dadurch, dass sie gleiche Aufgaben durch verschiedene Algorithmen lösen. Anstatt das Problem durch direkte Vererbung zu lösen, wird eine Klasse StrategyContext erstellt, die gemeinsame Operationen definiert. Die Signaturen der unterschiedlich zu implementierenden Operationen werden in der abstrakten Klasse Strategy zusammengefasst. Die Subklasse ConcreteStrategy überschreibt dann diese Methode.
Beispiel: Für eine Auftragsabwicklung braucht man eine Steuerberechnung, die länderabhängig ist. Anstatt die Subklasse D_Steuerrechner, A_Steuerrechner und CH_Steuerrechner einzuführen, definiert man einfach eine Methode berechneSteuer() und einen Steuerrechner als private Attribut. Dieser abstrakte Steuerrechner hat dann als Subklassen CH_Steuerrechner... Auf diese Weise trennt man Auftragsabwicklung und Steuerberechnung und hat innerhalb der Klassen einen besseren Zusammenhalt.
Decorator
Alternative zur Unterklassenbildung, um eine Klasse um zusätzliche Funktionalität zu erweitern. Der Dekorierer erbt von der zu dekorierenden Klasse und hat die gleiche Schnittstelle wie diese. Die Subklassen des Dekorierers sind konkrete Dekorierer und können zusätzliche Operationen oder Zustände bereitstellen. Der User merkt bei Verwendung der Klasse meist nicht, dass ein Dekorierer vorgeschaltet ist.
Fascade
Eine Klasse soll nur bestimmte Operationen einer anderen Klasse aufrufen können. Dies wird realisiert, indem man in einer Fassadenklasse nur die entsprechenden Methoden definiert, die sichtbar sein sollen. Diese delegieren den Aufruf dann an die Methoden der eigentlichen Klasse.
Adapter
Der Adapter wird eingesetzt, wenn man eine Methode verwenden möchte, deren Signatur nicht passt. Man schreibt sich eine Adapterklasse mit passender Signatur, die an die Klasse mit unpassender Signatur delegiert. Dabei werden z.B. bestimmte Parameter der nicht passenden Klasse mit Konstanten vorbelegt.
Observer
Mehrere Objekte sollen ein Objekt beobachten können und sollen bei Änderung informiert werden. Das beobachtete Objekt soll die genau Implementierung der Observer nicht kennen, lediglich festgelegte Schnittstellenmethoden.
Die Observer ergeben von der Oberklasse Observer oder implementieren ein entsprechendes Interface. Die beobachtete Klasse implementiert das Interface Observable, welches Methoden zum Benachrichtigen der Observer bereitstellt. Ändert sich das Observable ruft es notifyObservers() auf, welche ihrerseits die Methode getState() des Observables (über Schnittstelle definiert) aufrufen.
State
Für ein Objekt soll das Verhalten zustandsabhängig modelliert werden (z.B. sind die Zustandsübergänge in einem StateChart modelliert). Man möchte ständige if-Abfragen vermeiden.
Man hat eine Klasse StateContext, die sich zustandsabhängig verhalten soll. Diese kennt ihren State (abstrakte Klasse). Die State-Klasse besitzt alle Klassen des Zustandsautomaten als Unterklassen. Diese Unterklassen bieten die Methoden an, die in diesem State zugreifbar sind. Die Klasse StateContext delegiert die Methodenaufrufe an die State Klassen (also sagt so etwas wie this.state.doSomething())
Man bekommt bei diesem Pattern eine relativ saubere Struktur und benötigt wenig if-Abfragen. Allerdings produziert man evtl. viel redundanten Code.
Factory Method
Eine Klasse soll Objekte erzeugen, möchte diese aber nicht kennen und delegiert die Erzeugung der Objekte (und die Bestimmung welche Objekte erzeugt werden sollen) an Unterklassen.
Am Muster sind 4 Klassen beteiligt: Produkt, konkretes Produkt, Abstrakte Fabrik und konkrete Fabrik.
Beispielsweise möchte man Eis erzeugen, man weiß aber nicht genau welches, bzw. überlässt dies der Unterklasse. Man sagt dann Eisfabrik.erzeugeEis() und erhält dann ein Objekt des abstrakten Produkts Eis zurück. Die Eisfabrik könnte nun selbst entscheiden wie sie reagiert, also welches Eis sie erzeugt (z.B. zufällig Erdbeer oder Schokolade). Sie ruft dann konkret die Konstruktoren dieser konkreten Produkte auf und liefert das Eisobjekt zurück.
Die Aufruferklasse wird durch das Pattern von der Implementierung konkreter Produktklassen entkoppelt.
Template Method
Mehrere Algorithmen sind sich sehr ähnlich, unterscheiden sich aber durch einzelne Methoden.
Man implementiert eine abstrakte Oberklasse Algorithmus, die die Schablonenmethode apply() bereitstellt und die Gemeinsamkeiten zusammenfasst. In dieser Methode sind aber abstrakte Methoden eingebaut, die erst in den Unterklassen realisiert werden. So brauchen die Unterklassen nicht noch extra (redundant) den gemeinsamen Code implementieren.
Singleton
Es soll nur ein Objekt einer Klasse erstellt werden können. Dazu wird einfach in der Methode instanceOf() überprüft, ob schon ein Objekt der Klasse exisitiert. Wenn ja, wird das alte Objekt zurückgeliefert, wenn nein, wird das neue Objekt erstellt.
Strategy
Verwandte Klassen unterscheiden sich dadurch, dass sie gleiche Aufgaben durch verschiedene Algorithmen lösen. Anstatt das Problem durch direkte Vererbung zu lösen, wird eine Klasse StrategyContext erstellt, die gemeinsame Operationen definiert. Die Signaturen der unterschiedlich zu implementierenden Operationen werden in der abstrakten Klasse Strategy zusammengefasst. Die Subklasse ConcreteStrategy überschreibt dann diese Methode.
Beispiel: Für eine Auftragsabwicklung braucht man eine Steuerberechnung, die länderabhängig ist. Anstatt die Subklasse D_Steuerrechner, A_Steuerrechner und CH_Steuerrechner einzuführen, definiert man einfach eine Methode berechneSteuer() und einen Steuerrechner als private Attribut. Dieser abstrakte Steuerrechner hat dann als Subklassen CH_Steuerrechner... Auf diese Weise trennt man Auftragsabwicklung und Steuerberechnung und hat innerhalb der Klassen einen besseren Zusammenhalt.
Decorator
Alternative zur Unterklassenbildung, um eine Klasse um zusätzliche Funktionalität zu erweitern. Der Dekorierer erbt von der zu dekorierenden Klasse und hat die gleiche Schnittstelle wie diese. Die Subklassen des Dekorierers sind konkrete Dekorierer und können zusätzliche Operationen oder Zustände bereitstellen. Der User merkt bei Verwendung der Klasse meist nicht, dass ein Dekorierer vorgeschaltet ist.
Fascade
Eine Klasse soll nur bestimmte Operationen einer anderen Klasse aufrufen können. Dies wird realisiert, indem man in einer Fassadenklasse nur die entsprechenden Methoden definiert, die sichtbar sein sollen. Diese delegieren den Aufruf dann an die Methoden der eigentlichen Klasse.
Adapter
Der Adapter wird eingesetzt, wenn man eine Methode verwenden möchte, deren Signatur nicht passt. Man schreibt sich eine Adapterklasse mit passender Signatur, die an die Klasse mit unpassender Signatur delegiert. Dabei werden z.B. bestimmte Parameter der nicht passenden Klasse mit Konstanten vorbelegt.
Observer
Mehrere Objekte sollen ein Objekt beobachten können und sollen bei Änderung informiert werden. Das beobachtete Objekt soll die genau Implementierung der Observer nicht kennen, lediglich festgelegte Schnittstellenmethoden.
Die Observer ergeben von der Oberklasse Observer oder implementieren ein entsprechendes Interface. Die beobachtete Klasse implementiert das Interface Observable, welches Methoden zum Benachrichtigen der Observer bereitstellt. Ändert sich das Observable ruft es notifyObservers() auf, welche ihrerseits die Methode getState() des Observables (über Schnittstelle definiert) aufrufen.
State
Für ein Objekt soll das Verhalten zustandsabhängig modelliert werden (z.B. sind die Zustandsübergänge in einem StateChart modelliert). Man möchte ständige if-Abfragen vermeiden.
Man hat eine Klasse StateContext, die sich zustandsabhängig verhalten soll. Diese kennt ihren State (abstrakte Klasse). Die State-Klasse besitzt alle Klassen des Zustandsautomaten als Unterklassen. Diese Unterklassen bieten die Methoden an, die in diesem State zugreifbar sind. Die Klasse StateContext delegiert die Methodenaufrufe an die State Klassen (also sagt so etwas wie this.state.doSomething())
Man bekommt bei diesem Pattern eine relativ saubere Struktur und benötigt wenig if-Abfragen. Allerdings produziert man evtl. viel redundanten Code.
Factory Method
Eine Klasse soll Objekte erzeugen, möchte diese aber nicht kennen und delegiert die Erzeugung der Objekte (und die Bestimmung welche Objekte erzeugt werden sollen) an Unterklassen.
Am Muster sind 4 Klassen beteiligt: Produkt, konkretes Produkt, Abstrakte Fabrik und konkrete Fabrik.
Beispielsweise möchte man Eis erzeugen, man weiß aber nicht genau welches, bzw. überlässt dies der Unterklasse. Man sagt dann Eisfabrik.erzeugeEis() und erhält dann ein Objekt des abstrakten Produkts Eis zurück. Die Eisfabrik könnte nun selbst entscheiden wie sie reagiert, also welches Eis sie erzeugt (z.B. zufällig Erdbeer oder Schokolade). Sie ruft dann konkret die Konstruktoren dieser konkreten Produkte auf und liefert das Eisobjekt zurück.
Die Aufruferklasse wird durch das Pattern von der Implementierung konkreter Produktklassen entkoppelt.
Template Method
Mehrere Algorithmen sind sich sehr ähnlich, unterscheiden sich aber durch einzelne Methoden.
Man implementiert eine abstrakte Oberklasse Algorithmus, die die Schablonenmethode apply() bereitstellt und die Gemeinsamkeiten zusammenfasst. In dieser Methode sind aber abstrakte Methoden eingebaut, die erst in den Unterklassen realisiert werden. So brauchen die Unterklassen nicht noch extra (redundant) den gemeinsamen Code implementieren.
Flashcard info:
Author: ChristianK
Main topic: Informatik
Topic: Softwaretechnik
School / Univ.: RWTH Aachen
City: Aachen
Published: 24.04.2010