Entwurfsmuster - Design Pattern Entwurfsmuster - Design Pattern ...
Entwurfsmuster - Design Pattern Entwurfsmuster - Design Pattern ...
Entwurfsmuster - Design Pattern Entwurfsmuster - Design Pattern ...
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
<strong>Entwurfsmuster</strong> - <strong>Design</strong> <strong>Pattern</strong><br />
<strong>Entwurfsmuster</strong> - <strong>Design</strong> <strong>Pattern</strong><br />
Erste neuere Erfahrungen Ende der 80er Jahre<br />
<strong>Pattern</strong> für User Interfaces in Smalltalk von<br />
Cunningham und Beck<br />
C++ Idioms von Coplien<br />
Erich Gamma, Richard Helm, Ralph Johnson,<br />
John Vlissides (GoF) erarbeiteten Katalog von<br />
<strong>Pattern</strong> (1995) Standardwerk<br />
Ein <strong>Entwurfsmuster</strong> gibt eine bewährte<br />
generische Lösung für ein immer<br />
wiederkehrendes Entwurfsproblem, das<br />
in bestimmten Situationen auftritt.<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 1<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 2<br />
<strong>Pattern</strong> nach Gamma et. al.<br />
Mustername und Klassifizierung<br />
Zweck (kurze Darstellung des Musters)<br />
Auch bekannt als<br />
Motivation (exemplarisches Szenario)<br />
Anwendbarkeit (mögliche Verwendungen)<br />
Struktur (graphische Darstellung der strukturellen Eigenschaften)<br />
Akteure (beteiligte Klassen und Objekte)<br />
Konsequenzen (Vor- und Nachteile, Ergebnisse)<br />
Beispielcode<br />
Bekannte Verwendung<br />
Verwandte Muster (Unterschiede, Zusammenarbeit)<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 3<br />
<strong>Pattern</strong> nach Gamma et. al.<br />
Erzeugungsmuster Strukturmuster Verhaltensmuster<br />
Klasse Factory Method Adapter Interpreter<br />
Template Method<br />
Objekt Abstract Factory Adapter Chain of Responsibility<br />
Builder Bridge Commend<br />
Prototype Composite Iterator<br />
Singleton Decorator Mediator<br />
Facade<br />
Mementon<br />
Flywight<br />
Observer<br />
Proxy<br />
State<br />
Strategy<br />
Visitor<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 4<br />
<strong>Pattern</strong> nach Gamma et. al.<br />
Klassenmuster:<br />
– Beziehungen zwischen Klassen (Vererbungsstrukturen)<br />
– zur Übersetzungszeit festgelegt (statisch)<br />
Objektmuster:<br />
– Beziehungen zwischen Objekten<br />
– zur Laufzeit veränderbar (dynamisch)<br />
– nutzen auch in gewissem Grad Vererbung<br />
<strong>Pattern</strong> nach Gamma et. al.<br />
Erzeugungsmuster:<br />
– abstrahieren den Objekterzeugungsprozess<br />
– Klassenmuster nutzen Vererbung, um Teile der<br />
Objekterzeugung in Unterklassen zu verlagern<br />
– Objektmuster delegieren Objekterzeugung an ein<br />
anderes Objekt<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 5<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 6<br />
1
<strong>Pattern</strong> nach Gamma et. al.<br />
Strukturmuster:<br />
– setzen Klassen und Objekte zu größeren Strukturen<br />
zusammen<br />
– Klassenmuster nutzen Vererbung, um Schnittstellen und<br />
Implementierungen zusammenzuführen<br />
(einfaches Beispiel: Mehrfachvererbung)<br />
– hilfreich, um unabhängig voneinander entwickelte<br />
Bibliotheken zusammen arbeiten zu lassen<br />
– Objektmuster ermöglichen, Objekte zusammenzuführen<br />
– flexibler als Klassenmuster, da sich bei Objektstrukturen<br />
die Struktur zur Laufzeit ändern kann<br />
<strong>Pattern</strong> nach Gamma et. al.<br />
Verhaltensmuster:<br />
– beschreiben Interaktionen zwischen Objekten und<br />
Klassen und komplexe Kontrollflüsse<br />
– Klassenmuster verwenden Vererbung, um das Verhalten<br />
unter den Klassen zu verteilen<br />
– Objektmuster nutzen Aggregationen anstelle von<br />
Vererbung und beschreiben, wie Gruppen von Objekten<br />
zusammenarbeiten<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 7<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 8<br />
Klassenbibliotheken<br />
Menge wiederverwendbarer Klassen, die eine allgemeine<br />
Funktionalität zur Verfügung stellen<br />
unterschiedliche Topologien möglich:<br />
– Baum-Topologie (eine gemeinsame Wurzelklasse)<br />
– Wald-Topologie (mehrere Baumhierarchien)<br />
– Baustein-Topologie (unabhängige generische Klassen)<br />
Bibliotheken für unterschiedliche Anwendungsgebiete:<br />
z.B. Basisbibliotheken, GUI-Klassenbibliotheken, Bibliotheken zum<br />
Zugriff auf Datenbanken<br />
„einfache“ Klassenbibliotheken:<br />
– erzwingen keine bestimmte Anwendungsstruktur<br />
– Zweck: Code-Wiederverwendung<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 9<br />
Frameworks<br />
Menge zusammenarbeitender Klassen (konkrete und<br />
abstrakte), die einen wiederverwendbaren Entwurf<br />
implementieren<br />
Nutzung des Frameworks bedeutet, Unterklassen von den<br />
abstrakten Framework-Klassen abzuleiten<br />
Framework bestimmt Architektur der Anwendung (definiert<br />
Struktur der Klassen und Objekte, ihre Verantwortlichkeiten<br />
und ihr Zusammenspiel) und legt alle Entwurfsparameter<br />
fest<br />
immer spezifisch auf einen Anwendungsbereich ausgelegt<br />
Zweck: Entwurfs-Wiederverwendung<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 10<br />
<strong>Design</strong> <strong>Pattern</strong> vs. Frameworks<br />
<strong>Pattern</strong> Bridge<br />
<strong>Pattern</strong> sind abstrakter als Frameworks<br />
– werden nur beispielhaft durch Programmcode repräsentiert<br />
– sind immer mit einer neuen Implementierung verbunden<br />
<strong>Pattern</strong> sind kleiner als Frameworks<br />
– ein typisches Framework enthält mehrere <strong>Pattern</strong><br />
<strong>Pattern</strong> sind weniger spezialisiert als Frameworks<br />
– nicht auf einen bestimmten Anwendungsbereich beschränkt<br />
Zweck:<br />
Entkopplung einer Abstraktion von ihrer<br />
Implementation<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 11<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 12<br />
2
<strong>Pattern</strong> Bridge<br />
<strong>Pattern</strong> Bridge<br />
Klient<br />
Abstraktion<br />
Operation()<br />
SpezialisierteAbstraktion<br />
imp<br />
Implementierer<br />
OperationsImp()<br />
imp.OperationsImp()<br />
KonkreterImplementiererA KonkreterImplementiererB<br />
OperationsImp()<br />
OperationsImp()<br />
Akteure:<br />
Abstraktion<br />
• verwaltet eine Referenz auf einen Implementierer und definiert<br />
Schnittstelle<br />
SpezialisierteAbstraktion<br />
• erweitert die durch Abstraktion definierte Schnittstelle<br />
Implementierer<br />
• definiert Schnittstelle für Implementierungsklassen<br />
KonkreterImplementierer<br />
• definiert konkrete Implementation<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 13<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 14<br />
<strong>Pattern</strong> Bridge<br />
Anwendungsbedingungen:<br />
dauerhafte Verbindung zwischen Abstraktion und<br />
ihrer Implementierung soll vermieden werden<br />
sowohl Abstraktion als auch Implementierungen<br />
sollen durch Unterklassenbildung erweiterbar sein<br />
Änderungen in der Implementierung der Abstraktion<br />
sollen keine Auswirkungen auf Klienten haben<br />
Implementierung der Abstraktion soll vollständig vor<br />
Klienten versteckt werden<br />
Implementierung soll von mehreren Objekten<br />
gemeinsam genutzt werden<br />
<strong>Pattern</strong> Bridge<br />
Vor- und Nachteile:<br />
+ Entkopplung von Abstraktion und Implementation<br />
+ Die Implementation kann dynamisch während der<br />
Laufzeit verändert werden<br />
+ Verbesserte Erweiterbarkeit<br />
+ Implementation kann in Abhängigkeit von einem<br />
Parameter in der Erzeugungsroutine (Konstruktor)<br />
gewählt werden<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 15<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 16<br />
Übungsaufgabe<br />
Implementieren Sie in Eiffel das <strong>Entwurfsmuster</strong> Bridge, um<br />
die Abstraktion <strong>Pattern</strong>Stack von ihrer Implementation zu<br />
trennen.<br />
Die Schnittstelle der Abstraktion <strong>Pattern</strong>Stack enthält die<br />
Operationen push, top und pop.<br />
Als Implementationen sind die vorcompilierten Eiffel-Klassen<br />
TWO_WAY_LIST und SORTED_TWO_WAY_LIST zu nutzen.<br />
Testen Sie die Funktionsweise Ihres Brückenmusters<br />
beispielhaft in einer Testklasse.<br />
<strong>Pattern</strong> Adapter<br />
Zweck:<br />
Anpassen der Schnittstellen inkompatibler<br />
Klassen<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 17<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 18<br />
3
<strong>Pattern</strong> Adapter<br />
<strong>Pattern</strong> Adapter<br />
Klassenadapter (verwendet Mehrfachvererbung)<br />
Objektadapter (verwendet Objektkomposition)<br />
Klient<br />
Ziel<br />
AdaptierteKlasse<br />
Klient<br />
Ziel<br />
AdaptierteKlasse<br />
Operation()<br />
SpezifischeOperation()<br />
Operation()<br />
SpezifischeOperation()<br />
adaptiertesObjekt<br />
(implementierung)<br />
Adapter<br />
Adapter<br />
Operation()<br />
SpezifischeOperation()<br />
Operation()<br />
adaptiertesObjekt.SpezifischeOperation()<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 19<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 20<br />
<strong>Pattern</strong> Adapter<br />
<strong>Pattern</strong> Adapter<br />
Akteure:<br />
Ziel<br />
• definiert anwendungsspezifische Schnittstelle<br />
Klient<br />
• arbeitet mit Objekten, die der Zielschnittstelle entsprechen<br />
AdaptierteKlasse<br />
• definiert existierende und anzupassende Schnittstelle<br />
Adapter<br />
• passt Schnittstelle der anzupassenden Klasse an die<br />
Zielschnittstelle an<br />
Anwendungsbedingungen:<br />
Wenn eine existierende Klasse verwendet werden<br />
soll, deren Schnittstelle nicht der benötigten<br />
Schnittstelle entspricht<br />
Wenn eine wiederverwendbare Klasse erstellt werden<br />
soll, die mit unabhängigen oder nicht vorhersehbaren<br />
Klassen zusammenarbeiten muss<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 21<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 22<br />
<strong>Pattern</strong> Adapter<br />
<strong>Pattern</strong> Adapter<br />
Klassenadapter<br />
Vor- und Nachteile:<br />
+ passt die zu adaptierende Klasse an genau eine<br />
konkrete Zielklasse an<br />
- funktioniert nicht, wenn eine Klasse und alle ihre<br />
Unterklassen angepasst werden sollen<br />
+ Adapter kann Verhalten der adaptierten Klasse<br />
einfach überschreiben<br />
Objektadapter<br />
Vor- und Nachteile:<br />
+ Adapter kann mit mehreren anzupassenden Klassen<br />
arbeiten (der Klasse selbst und allen ihren<br />
Unterklassen)<br />
- Überschreiben des Verhaltens der anzupassenden<br />
Klasse schwieriger (Unterklassenbildung nötig)<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 23<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 24<br />
4
<strong>Pattern</strong> Proxy<br />
<strong>Pattern</strong> Proxy<br />
Zweck:<br />
Kontrolle des Zugriffes auf ein Objekt mit Hilfe<br />
eines vorgelagerten Stellvertreterobjektes<br />
Klient<br />
Subjekt<br />
Operation()<br />
EchtesSubjekt<br />
Proxy<br />
Operation()<br />
echtes<br />
Subjekt<br />
Operation()<br />
echtesSubjekt.Operation()<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 25<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 26<br />
<strong>Pattern</strong> Proxy<br />
<strong>Pattern</strong> Proxy<br />
Akteure:<br />
Proxy<br />
– verwaltet Referenz auf EchtesSubjekt<br />
– bietet Schnittstelle, die mit der von Subjekt identisch ist<br />
– kontrolliert Zugriff auf EchtesSubjekt<br />
Subjekt<br />
– definiert gemeinsame Schnittstelle von EchtesSubjekt und<br />
Proxy<br />
EchtesSubjekt<br />
– definiert das eigentliche Objekt, das durch Proxy<br />
repräsentiert wird<br />
Arten des Proxy-Musters:<br />
Remote-Proxy<br />
– stellt einen lokalen Stellvertreter für ein Objekt in einem<br />
anderen Adressraum dar<br />
Virtuelles Proxy<br />
– erzeugt „teure“ Objekte auf Verlangen<br />
– Copy-On-Write (kopiert ein aufwändiges Objekt erst dann,<br />
wenn es wirklich verändert wurde)<br />
Schutzproxy<br />
– kontrolliert Zugriff auf das Originalobjekt<br />
– nützlich, wenn Objekte über unterschiedliche Zugriffsrechte<br />
verfügen sollen<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 27<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 28<br />
<strong>Pattern</strong> Visitor<br />
Besucher<br />
BesucheKonkretesElementA(KonkretesElementA)<br />
BesucheKonkretesElementB(KonkretesElementB)<br />
Zweck:<br />
Kapselung einer auf den Elementen einer<br />
Objektstruktur auszuführenden Operation<br />
als ein Objekt.<br />
Definition einer neuen Operation ohne<br />
Veränderung der Klassen der von ihr<br />
bearbeiteten Elemente.<br />
KonkreterBesucher1<br />
BesucheKonkretesElementA(KonkretesElementA)<br />
BesucheKonkretesElementB(KonkretesElementB)<br />
Klient<br />
ObjektStruktur<br />
KonkretesElementA<br />
NimmEntgegen(Besucher b)<br />
OperationA()<br />
KonkreterBesucher2<br />
BesucheKonkretesElementA(KonkretesElementA)<br />
BesucheKonkretesElementB(KonkretesElementB)<br />
Element<br />
NimmEntgegen(Besucher)<br />
KonkretesElementB<br />
NimmEntgegen(Besucher b)<br />
OperationB()<br />
b.BesucheKonkretesElementA(Current)<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 29<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 30<br />
5
<strong>Pattern</strong> Visitor<br />
Akteure:<br />
Besucher<br />
– deklariert Besuche-Operation für jede KonkretesElement-<br />
Klasse<br />
– Operationsname und Signatur benennen Klasse, welche<br />
Besuche-Operation des Besuchers aufruft<br />
– dies ermöglicht Besucher, konkrete Klasse des besuchten<br />
Elementes zu bestimmen<br />
KonkreterBesucher<br />
– implementiert jede von der Besucher-Klasse deklarierte<br />
Operation<br />
<strong>Pattern</strong> Visitor<br />
Akteure:<br />
Element<br />
– definiert NimmEntgegen-Operation, die einen Besucher als<br />
Argument empfangen kann<br />
KonkretesElement<br />
– implementiert NimmEntgegen-Operation<br />
Objektstruktur (Klient)<br />
– kann seine Elemente aufzählen<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 31<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 32<br />
<strong>Pattern</strong> Visitor<br />
<strong>Pattern</strong> Visitor<br />
Anwendungsbedingungen:<br />
auf Objekten einer Objektstruktur müssen viele<br />
unterschiedliche, nicht miteinander verwandte<br />
Operationen ausgeführt werden<br />
Klassen, die die Objektstruktur definieren, ändern sich<br />
nicht<br />
es werden aber häufig neue Operationen für die<br />
Struktur definiert<br />
Vor- und Nachteile:<br />
+ einfaches Hinzufügen neuer Operationen durch<br />
Definieren eines neuen Besuchers<br />
+ Besucher vereinigt verwandte Operationen und trennt<br />
sie von Operationen, die nichts mit der Aufgabe des<br />
Besuchers zu tun haben<br />
+ Klassenhierarchieübergreifende Besucher möglich<br />
- Hinzufügen neuer KonkretesElement-Klassen<br />
schwierig<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 33<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 34<br />
Übungsaufgabe<br />
Implementieren Sie in Eiffel das <strong>Entwurfsmuster</strong> Visitor,<br />
indem Sie über der Objektstruktur eines binären Baumes<br />
(Klasse BINARY_TREE), der Integer-Werte hält, drei<br />
Durchläufe mit je einem Besucher realisieren.<br />
Der erste Besucher gibt jeweils den Wert aus, der zweite<br />
Besucher verdoppelt ihn und der dritte Besucher<br />
summiert die Werte auf.<br />
Testen Sie die Funktionsweise Ihres Besuchermusters<br />
beispielhaft in einer Testklasse.<br />
<strong>Pattern</strong> Observer<br />
Zweck:<br />
Definiert eine 1:n-Beziehung zwischen<br />
Objekten, so dass bei Änderung des<br />
Zustandes eines Objektes alle abhängigen<br />
Objekte benachrichtigt und automatisch<br />
aktualisiert werden.<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 35<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 36<br />
6
<strong>Pattern</strong> Observer<br />
<strong>Pattern</strong> Observer<br />
Akteure:<br />
Subjekt<br />
MeldeAn(Beobachter)<br />
MeldeAb(Beobachter)<br />
Benachrichtige()<br />
KonkretesSubjekt<br />
subjektZustand<br />
GibZustand()<br />
SetzeZustand()<br />
beobachter<br />
Für alle b in beobachter:<br />
b.Aktualisiere()<br />
Result:=subjektZustand<br />
beobachterZustand :=<br />
subjekt.GibZustand()<br />
subjekt<br />
Beobachter<br />
Aktualisiere()<br />
KonkreterBeobachter<br />
beobachterZustand<br />
Aktualisiere()<br />
<br />
<br />
<br />
<br />
Subjekt<br />
– kennt Liste von Beobachtern (keine konkreten Beobachter)<br />
– bietet Schnittstelle zum An- und Abmelden von Beobachtern<br />
KonkretesSubjekt<br />
– speichert den für KonkreteBeobachter relevanten Zustand<br />
– benachrichtigt Beobachter, wenn sich sein Zustand ändert<br />
Beobachter<br />
– definiert Aktualisierungsschnittstelle für Objekte, die über<br />
Änderungen eines Subjektes benachrichtigt werden müssen<br />
KonkreterBeobachter<br />
– verwaltet Referenz auf ein KonkretesSubjekt<br />
– speichert den zu dem des Subjektes konsistenten Zustand<br />
– implementiert Aktualisierungsschnittstelle von Beobachter<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 37<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 38<br />
<strong>Pattern</strong> Observer<br />
<strong>Pattern</strong> Observer<br />
Anwendungsbedingungen:<br />
Wenn eine Abstraktion zwei Aspekte besitzt, von<br />
denen der eine vom anderen abhängt.<br />
Wenn die Änderung eines Objektes die Änderung<br />
anderer Objekte verlangt.<br />
Wenn ein Objekt andere Objekte benachrichtigen soll,<br />
ohne zu wissen, wer diese anderen Objekte sind.<br />
Vor- und Nachteile:<br />
+ Subjekte und Beobachter können unabhängig<br />
voneinander variiert werden<br />
+ abstrakte und minimale Kopplung zwischen<br />
Subjekt und Beobachter<br />
+ Unterstützung der Broadcast-Kommunikation<br />
- unerwartete Aktualisierungen hohen Aufwandes<br />
möglich<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 39<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 40<br />
Übungsaufgabe<br />
Implementieren Sie in Eiffel das <strong>Entwurfsmuster</strong> Observer<br />
für folgendes Szenario:<br />
Eine Klasse (Subjekt) hält die Datumsangaben Jahr, Monat,<br />
Tag und kann diese auch ändern.<br />
Zwei Beobachterklassen beobachten das Subjekt und<br />
stellen Änderungen des Subjektzustandes in<br />
unterschiedlicher Form dar<br />
(TT.MM.YYYY und MM/TT/YYYY).<br />
Testen Sie die Funktionsweise Ihres Beobachtermusters<br />
beispielhaft in einer Testklasse.<br />
<strong>Pattern</strong> Strategy<br />
Zweck:<br />
Definiert eine Familie von Algorithmen,<br />
kapselt jeden einzelnen und macht ihn<br />
austauschbar.<br />
Algorithmen können unabhängig von den<br />
Klienten verändert werden.<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 41<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 42<br />
7
<strong>Pattern</strong> Strategy<br />
<strong>Pattern</strong> Strategy<br />
Klient<br />
Kontext<br />
strategie<br />
KontextSchnittstelle()<br />
KonkreteStrategieA<br />
AlgorithmusSchnittstelle()<br />
Strategie<br />
AlgorithmusSchnittstelle()<br />
KonkreteStrategieB<br />
AlgorithmusSchnittstelle()<br />
KonkreteStrategieC<br />
AlgorithmusSchnittstelle()<br />
Akteure:<br />
Strategie<br />
– deklariert Schnittstelle, die von allen unterstützten<br />
Algorithmen angeboten wird<br />
KonkreteStrategie<br />
– implementiert Algorithmus unter Verwendung der<br />
Strategieschnittstelle<br />
Kontext<br />
– wird mit einem KonkreteStrategie-Objekt konfiguriert<br />
– verwaltet Referenz auf das Strategieobjekt<br />
– kann Schnittstelle definieren, die Strategieobjekten den<br />
Zugriff auf die Daten des Kontextes ermöglicht<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 43<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 44<br />
<strong>Pattern</strong> Strategy<br />
<strong>Pattern</strong> Strategy<br />
Anwendungsbedingungen:<br />
Wenn sich viele verwandte Klassen nur in ihrem<br />
Verhalten unterscheiden.<br />
Wenn unterschiedliche Varianten eines Algorithmus<br />
benötigt werden.<br />
Wenn eine Klasse unterschiedliche Verhaltensweisen<br />
definiert und diese als Mehrfachverzweigungen in<br />
ihren Operationen erscheinen.<br />
Wenn ein Algorithmus Daten verwendet, die Klienten<br />
nicht bekannt sein sollen.<br />
Vor- und Nachteile:<br />
+ Familien von verwandten Algorithmen festgelegt<br />
+ Alternative zur Unterklassenbildung<br />
+ Strategien entfernen Mehrfachverzweigungen<br />
+ Auswahlmöglichkeit für Implementierungen<br />
- Klienten müssen unterschiedliche Strategien kennen<br />
- Kommunikationsaufwand zwischen Strategie und<br />
Kontext<br />
- erhöhte Anzahl von Objekten<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 45<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 46<br />
<strong>Pattern</strong> Mediator<br />
<strong>Pattern</strong> Mediator<br />
Zweck:<br />
Steuerung der Kommunikation zwischen<br />
Objekten.<br />
Objekte kommunizieren nicht direkt, sondern<br />
immer über den Vermittler.<br />
Die Einbeziehung neuer Objekte ist auf die<br />
Veränderung des Vermittlers beschränkt.<br />
Vermittler<br />
KonkreterVermittler<br />
vermittler<br />
KonkreterKollege1<br />
Kollege<br />
KonkreterKollege2<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 47<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 48<br />
8
<strong>Pattern</strong> Mediator<br />
<strong>Pattern</strong> Mediator<br />
Akteure:<br />
Vermittler<br />
– definiert Schnittstelle für Interaktion mit den Kollegen-<br />
Objekten<br />
KonkreterVermittler<br />
– implementiert das Gesamtverhalten durch Koordination der<br />
Kollegen-Objekte<br />
– kennt und verwaltet Kollegen-Objekte<br />
Kollegen-Klassen<br />
– jede Kollegen-Klasse kennt ihre Vermittler-Klasse<br />
– jedes Kollegen-Objekt kommuniziert mit dem Vermittler,<br />
wenn es normalerweise direkt mit einem anderen Objekt<br />
Kontakt aufnehmen würde<br />
Anwendungsbedingungen:<br />
Wenn eine Menge von Objekten in komplexer Weise<br />
zusammenarbeitet.<br />
Wenn die Wiederverwendung eines Objektes<br />
schwierig ist, weil es sich auf viele andere Objekte<br />
bezieht.<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 49<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 50<br />
<strong>Pattern</strong> Mediator<br />
Vor- und Nachteile:<br />
+ Unterklassenbildung wird eingeschränkt<br />
(Änderung des Verhaltens erfordert lediglich<br />
Ableitung der Vermittler-Klasse)<br />
+ fördert lose Kopplung zwischen den Kollegen-<br />
Objekten<br />
+ vereinfacht das Protokoll des Objektes<br />
+ zentralisiert die Steuerung (Komplexität des<br />
Vermittlers beachten !)<br />
Übungsaufgabe<br />
Implementieren Sie in Eiffel das <strong>Entwurfsmuster</strong> Mediator<br />
für folgendes Szenario:<br />
Die Kollegen-Klassen verfügen über die Methoden<br />
Meldung_absetzen(int_zahl) und Meldung_empfangen(int_zahl), die<br />
zur Kommunikation untereinander dienen. Die<br />
Kommunikation erfolgt nicht direkt, sondern über einen<br />
Vermittler.<br />
Der Vermittler verwaltet die angemeldeten Kollegen und<br />
implementiert folgende Operationen: Kollege_anmelden,<br />
Kollege_abmelden und Alle_informieren.<br />
Testen Sie die Funktionsweise Ihres Vermittlermusters<br />
beispielhaft in einer Testklasse.<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 51<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 52<br />
Erzeugungsmuster<br />
Beispiel Mazegame 1 (original)<br />
Klassenmuster<br />
Objektmuster<br />
FactoryMethod<br />
(Verschieben der Objekterzeugung auf<br />
die Unterklasse)<br />
AbstractFactory<br />
(Erzeugung von „Gruppen“ von Objekten)<br />
Builder (Erzeugung komplexer Objekte)<br />
Prototype (Erzeugung eines Objektes als<br />
Kopie eines Prototype-Objektes)<br />
Singleton (Erzeugung von nur einer<br />
Instanz)<br />
class MAZEGAME<br />
feature<br />
CreateMaze: MAZE is<br />
local r1,r2: ROOM; d: DOOR; w: WALL;<br />
do<br />
!!Result;<br />
!!r1.make(1); !!r2.make(2); !!d.make(r1,r2);<br />
Result.AddRoom(r1); Result.AddRoom(r2);<br />
!!w; r1.SetSide("North",w);<br />
r1.SetSide("East",d);<br />
!!w; r1.SetSide("South",w);<br />
!!w; r1.SetSide("West",w); ............<br />
end<br />
end<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 53<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 54<br />
9
Beispiel Mazegame 2 (original)<br />
<strong>Pattern</strong> Abstract Factory<br />
class CLIENT<br />
creation<br />
make<br />
feature<br />
make is<br />
local game: MAZEGAME;<br />
aMaze: MAZE;<br />
do<br />
!!game;<br />
aMaze := game.CreateMaze<br />
end<br />
end<br />
Zweck:<br />
stellt eine Schnittstelle bereit, um Familien von<br />
Objekten zur Laufzeit zu erzeugen, ohne deren<br />
konkrete Klassen festzulegen<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 55<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 56<br />
<strong>Pattern</strong> Abstract Factory<br />
<strong>Pattern</strong> Abstract Factory<br />
KonkreteFabrik1<br />
ErzeugeProduktA()<br />
ErzeugeProduktB()<br />
AbstrakteFabrik<br />
ErzeugeProduktA()<br />
ErzeugeProduktB()<br />
KonkreteFabrik2<br />
ErzeugeProduktA()<br />
ErzeugeProduktB()<br />
Klient<br />
AbstraktesProduktA<br />
ProduktA2 ProduktA1<br />
AbstraktesProduktB<br />
ProduktB2 ProduktB1<br />
Anwendungsbedingungen:<br />
Wenn ein System unabhängig von der Art der<br />
Erzeugung seiner Produkte (Objekte) arbeiten soll.<br />
Wenn ein System mit einer von mehreren<br />
Produktfamilien konfiguriert werden soll.<br />
Wenn eine Gruppe von Produkten erzeugt werden<br />
soll, um gemeinsam genutzt zu werden.<br />
Wenn in einer Klassenbibliothek nur die<br />
Schnittstellen von Produkten bereitgestellt werden<br />
sollen und nicht die Implementationen.<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 57<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 58<br />
<strong>Pattern</strong> Abstract Factory<br />
Vor- und Nachteile:<br />
+ Isolierung konkreter Klassen<br />
+ Austausch von Produktfamilien ist einfach<br />
+ Produktnutzung nur eines Produktes aus einer<br />
Gruppe wird gesichert<br />
- neue Produktarten sind schwer einfügbar<br />
Verwendung:<br />
Benutzungsschnittstellen mit unterschiedlichem<br />
„Look and Feel“<br />
Mazegame mit Abstract Factory (1)<br />
deferred class MAZE_FACTORY<br />
feature<br />
end<br />
MakeMaze:MAZE is deferred end;<br />
MakeRoom (no:INTEGER) : ROOM is deferred end;<br />
MakeDoor (r1,r2:ROOM) : DOOR is deferred end;<br />
MakeWall: WALL is deferred end;<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 59<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 60<br />
10
Mazegame mit Abstract Factory (2)<br />
class ENCHANTED_MAZE_FACTORY<br />
inherit MAZE_FACTORY<br />
feature<br />
MakeRoom (no:INTEGER) : ENCHANTED_ROOM is<br />
do !!Result.make(no); end<br />
MakeWall: WALL is<br />
do !!Result; end<br />
MakeDoor (r1,r2:ROOM) :LOCKED_DOOR is<br />
do !!Result.make(r1,r2); end<br />
MakeMaze: MAZE is<br />
do !!Result; end<br />
end<br />
Mazegame mit Abstract Factory (3)<br />
class GAME_WITH_ABSTRACT_FACTORY<br />
feature<br />
CreateMaze (fac:MAZE_FACTORY): MAZE is<br />
local r1,r2: ROOM; d: DOOR;<br />
do r1 := fac.MakeRoom (1); r2 := fac.MakeRoom (2);<br />
d :=fac.MakeDoor (r1,r2);<br />
Result := fac.MakeMaze; Result.AddRoom (r1);<br />
Result.AddRoom (r2);<br />
r1.SetSide ("North",fac.MakeWall);<br />
r1.SetSide ("East",d);<br />
r1.SetSide ("South",fac.MakeWall);<br />
r1.SetSide ("West",fac.MakeWall); ....<br />
end<br />
end<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 61<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 62<br />
Mazegame mit Abstract Factory (4)<br />
<strong>Pattern</strong> Builder<br />
class CLIENT<br />
creation<br />
make<br />
feature<br />
make is<br />
local game: GAME_WITH_ABSTRACT_FACTORY<br />
fac: ENCHANTED_MAZE_FACTORY;<br />
aMaze: MAZE;<br />
do<br />
!!game; !!fac;<br />
aMaze := game.CreateMaze (fac);<br />
end<br />
end<br />
Zweck:<br />
Trennung der Konstruktion komplexer Objekte von ihrer<br />
Repräsentation.<br />
Dadurch kann der gleiche Prozess verschiedene<br />
Repräsentationen erzeugen.<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 63<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 64<br />
<strong>Pattern</strong> Builder<br />
<strong>Pattern</strong> Builder<br />
Klient<br />
Direktor<br />
Erbauer<br />
Anwendungsbedingungen:<br />
Konstruiere()<br />
für alle Objekte in der Struktur:<br />
erbauer.BaueTeil()<br />
BaueTeil()<br />
KonkreterErbauer<br />
BaueTeil()<br />
GibErgebnis()<br />
Produkt<br />
Wenn die Erzeugung eines komplexen Objektes<br />
unabhängig von der Erzeugung seiner Bestandteile<br />
und ihrer Komposition sein soll.<br />
Wenn verschiedene Repräsentationen des<br />
komplexen Objektes erlaubt sein sollen.<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 65<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 66<br />
11
<strong>Pattern</strong> Builder<br />
Akteure:<br />
Erbauer<br />
– spezifiziert eine abstrakte Schnittstelle zur Erzeugung<br />
von Teilen eines Produktes<br />
konkreterErbauer<br />
– liefert Implementation zur Schnittstelle<br />
– definiert und verwaltet die von ihm erzeugte Repräsentation<br />
– bietet Schnittstelle zum Zurückgeben des Produktes<br />
Direktor<br />
– konstruiert ein Objekt entsprechend Erbauerschnittstelle<br />
Produkt<br />
– repräsentiert das gerade konstruierte komplexe Objekt<br />
Vorteile:<br />
+ isoliert Code für Konstruktion und Repräsentation<br />
+ Änderung der Repräsentation durch neue konkrete<br />
Erbauer-Klasse<br />
Verwendung:<br />
<strong>Pattern</strong> Builder<br />
Konvertierungs-Applikationen<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 67<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 68<br />
Mazegame mit Builder (1)<br />
deferred class MAZE_BUILDER<br />
feature<br />
maze: MAZE is deferred end<br />
BuildMaze is do end<br />
BuildRoom (no:INTEGER) is do end<br />
BuildDoor (r1,r2:INTEGER) is do end<br />
end<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 69<br />
Mazegame mit Builder (2)<br />
class STANDARD_MAZE_BUILDER<br />
inherit MAZE_BUILDER<br />
redefine BuildMaze, BuildRoom, BuildDooor<br />
end<br />
feature<br />
maze: MAZE<br />
BuildMaze is do !!maze; end<br />
BuildRoom (no:INTEGER) is<br />
local r: ROOM; w: WALL;<br />
do<br />
!!r.make (no); maze.AddRoom (r);<br />
!!w; r.SetSide ("North",w);<br />
!!w; r.SetSide ("East",w);<br />
!!w; r.SetSide ("South",w);<br />
!!w; r.SetSide ("West",w);<br />
end<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 70<br />
Mazegame mit Builder (3)<br />
BuildDoor (r1, r2:INTEGER) is<br />
local r1,r2: ROOM; d: DOOR;<br />
do<br />
r1 := maze.room (rno1); r2 := maze.room (rno2);<br />
!!d.make(r1,r2);<br />
r1.SetSide („East“, d);<br />
r2.SetSide („West“, d);<br />
end<br />
end<br />
Mazegame mit Builder (4)<br />
class MAZEGAME<br />
feature<br />
CreateMaze (builder:MAZE_BUILDER):MAZE is<br />
do<br />
builder.BuildMaze;<br />
builder.BuildRoom(1);<br />
builder.BuildRoom(2);<br />
builder.BuildDoor(1,2);<br />
Result := builder.maze;<br />
end<br />
end<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 71<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 72<br />
12
Mazegame mit Builder (5)<br />
class CLIENT<br />
creation make<br />
feature<br />
make is<br />
local<br />
game: MAZEGAME;<br />
aMaze: MAZE;<br />
aBuilder: MAZE_BUILDER;<br />
do !!game;<br />
!STANDARD_MAZE_BUILDER!aBuilder;<br />
aMaze := game.CreateMaze (aBuilder);<br />
end<br />
end<br />
<strong>Pattern</strong> Prototype<br />
Zweck:<br />
Prototypische Objekte werden zur Erzeugung<br />
weiterer Objekte genutzt.<br />
Neue Objekte werden durch Kopieren des<br />
Prototypen erzeugt.<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 73<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 74<br />
<strong>Pattern</strong> Prototype<br />
<strong>Pattern</strong> Prototype<br />
Klient<br />
Operation()<br />
p := Clone(prototyp)<br />
Prototyp<br />
Clone()<br />
KonkreterPrototyp1<br />
Clone()<br />
KonkreterPrototyp2<br />
Clone()<br />
Anwendungsbedingungen:<br />
Wenn die zu instanzierenden Klassen erst zur<br />
Laufzeit spezifiziert werden.<br />
Wenn vermieden werden soll, dass eine Hierarchie<br />
von Fabriken parallel zu einer Hierarchie von<br />
Produkten verläuft.<br />
Wenn die Objekte einer Klasse nur wenige<br />
unterschiedliche Zustandskombinationen haben<br />
können.<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 75<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 76<br />
<strong>Pattern</strong> Prototype<br />
Vor- und Nachteile:<br />
+ neue Produktklassen können zur Laufzeit<br />
eingebunden werden<br />
+ neue Objekte können durch Variation der Struktur<br />
spezifiziert werden<br />
+ verringerte Unterklassenbildung (keine Erzeuger-<br />
Klassenhierarchie)<br />
- jede Prototype-Unterklasse muss Clone-Operation<br />
implementieren (flache vs. tiefe Kopie)<br />
- gewünschte Initialisierungen des geklonten Objektes<br />
müssen separat erfolgen<br />
<strong>Pattern</strong> Prototype<br />
class PROTOTYPE_FACTORY<br />
feature<br />
proto_instance: Prototype;<br />
...<br />
new_instance: Prototype is<br />
do<br />
Result := deep_clone (proto_instance);<br />
end;<br />
...<br />
end<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 77<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 78<br />
13
<strong>Pattern</strong> Prototype (1)<br />
class MAZE_PROTOTYPE_FACTORY<br />
inherit MAZE_FACTORY<br />
creation make<br />
feature<br />
make (m: MAZE; w: WALL; r: ROOM; d:DOOR) is<br />
do prototype_maze := m; prototype_wall := w;<br />
prototype_room :=r; prototype_door := d;<br />
end<br />
MakeMaze: MAZE is<br />
do Result := clone (prototype_maze) end<br />
.....<br />
feature {NONE}<br />
prototype_maze: MAZE; prototype_wall: WALL;<br />
prototype_room: ROOM; prototype_door: DOOR<br />
end<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 79<br />
<strong>Pattern</strong> Prototype (2)<br />
class GAME_WITH_PROTOTYPE<br />
inherit GAME_WITH_ABSTRACT_FACTORY<br />
creation make<br />
feature<br />
make is<br />
local ......<br />
do !!maze; !!wall; !!room.make (0); !!door.make (Void, Void);<br />
!!maze_prototype_factory.make (maze, wall, room, door);<br />
aMaze := CreateMaze (maze_prototype_factory);<br />
!ENCHANTED_ROOM!room.make (0);<br />
!LOCKED_DOOR!door.make (Void,Void);<br />
!!maze_prototype_factory.make (maze, wall, room, door);<br />
aMaze := CreateMaze (maze_prototype_factory);<br />
end<br />
end<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 80<br />
<strong>Pattern</strong> Factory Method<br />
<strong>Pattern</strong> Factory Method<br />
Zweck:<br />
Erzeuger<br />
Definiert eine Schnittstelle zur Erzeugung eines<br />
Objektes, wobei die Unterklassen entscheiden, von<br />
welcher Klasse das zu erzeugende Objekt ist<br />
(virtueller Konstruktor).<br />
Produkt<br />
KonkretesProdukt<br />
erzeugt<br />
Fabrikmethode()<br />
EineOperation()<br />
KonkreterErzeuger<br />
produkt = Fabrikmethode()<br />
Fabrikmethode()<br />
Result := !!konkretesProdukt<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 81<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 82<br />
<strong>Pattern</strong> Factory Method<br />
Anwendungsbedingungen:<br />
Wenn eine Klasse die von ihr zu erzeugenden<br />
Objekte, nicht im voraus kennen kann.<br />
Wenn eine Klasse benötigt wird, deren Unterklassen<br />
selber festlegen, welche Objekte sie erzeugen.<br />
<strong>Pattern</strong> Factory Method<br />
Vor- und Nachteile:<br />
+ Spezialisierungsmöglichkeiten für Unterklassen<br />
(flexibler als direktes Erzeugen der Objekte)<br />
+ Verbindung paralleler Klassenhierarchien möglich<br />
- Probleme, wenn Fabrikmethode keine Default-<br />
Implementierung besitzt Zwang zur<br />
Unterklassenbildung<br />
Verwendung:<br />
Toolkits und Frameworks<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 83<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 84<br />
14
Mazegame mit Factory Method (1)<br />
class GAME_WITH_FACTORY_METHOD<br />
feature -- Factory Methods<br />
CreateMaze: MAZE is<br />
local r1,r2: ROOM; d: DOOR;<br />
do Result := MakeMaze;<br />
r1 := MakeRoom (1); r2 := MakeRoom (2);<br />
d := MakeDoor (r1,r2);<br />
Result.AddRoom (r1); Result.AddRoom (r2);<br />
r1.SetSide ("North",MakeWall);<br />
r1.SetSide ("East",d);<br />
r1.SetSide ("South",MakeWall);<br />
r1.SetSide ("West",MakeWall); ....<br />
end<br />
Mazegame mit Factory Method (2)<br />
end<br />
MakeMaze: MAZE is<br />
do !!Result end<br />
MakeRoom (no:INTEGER) : ROOM is<br />
do !!Result.make(no) end<br />
MakeWall: WALL is<br />
do !!Result end<br />
MakeDoor (r1,r2:ROOM) :DOOR is<br />
do !!Result.make(r1,r2); end<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 85<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 86<br />
<strong>Pattern</strong> Singleton<br />
<strong>Pattern</strong> Singleton<br />
Zweck:<br />
stellt sicher, dass eine Klasse genau ein<br />
Objekt besitzt und ermöglicht einen<br />
globalen Zugriff auf dieses Objekt.<br />
Singleton<br />
einzigesExemplar<br />
singletonDaten<br />
Exemplar()<br />
SingletonOperation()<br />
GibSingletonDaten()<br />
Result:=einzigesExemplar<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 87<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 88<br />
<strong>Pattern</strong> Singleton<br />
<strong>Pattern</strong> Singleton<br />
Anwendungsbedingungen:<br />
Wenn es genau ein Objekt einer Klasse geben und<br />
ein einfacher Zugriff darauf bestehen soll.<br />
Wenn das einzige Exemplar durch Spezialisierung<br />
mittels Unterklassen erweitert wird.<br />
Vor- und Nachteile:<br />
+ Zugriffskontrolle auf das Exemplar durch<br />
Singleton-Klasse<br />
+ Singleton-Klasse kann durch Unterklassen<br />
spezialisiert werden<br />
+ Werden später mehrere Exemplare benötigt,<br />
kann diese Änderung leicht durchgeführt werden<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 89<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 90<br />
15
<strong>Pattern</strong> Singleton (1)<br />
<strong>Pattern</strong> Singleton (2)<br />
class SINGLETON<br />
feature {NONE}<br />
the_singleton: SINGLETON is<br />
once<br />
Result := Current;<br />
end<br />
invariant<br />
only_one_instance: Current = the_singleton<br />
end<br />
deferred class SINGLETON_ACCESS<br />
feature {NONE}<br />
singleton: SINGLETON is deferred end<br />
is_real_singleton: BOOLEAN is<br />
do<br />
Result := singleton=singleton<br />
end<br />
end<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 91<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 92<br />
<strong>Pattern</strong> Singleton (3)<br />
class MAZE_FACTORY_ACCESS<br />
inherit SINGLETON_ACCESS<br />
redefine singleton<br />
end<br />
feature<br />
singleton: MAZE_FACTORY is -- Klasse MAZE_FACTORY<br />
once !!Result<br />
-- muss von SINGLETON erben<br />
end<br />
new_maze: MAZE is<br />
do Result := singleton.MakeMaze end<br />
new_room (no:INTEGER): ROOM is<br />
do Result := singleton.MakeRoom end .......<br />
end<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 93<br />
<strong>Pattern</strong> Singleton (4)<br />
class GAME_WITH_SINGLETON_FACTORY<br />
creation make<br />
feature {NONE} aMaze: MAZE;<br />
feature<br />
make is<br />
local maze_fac: MAZE_FACTORY_ACCESS<br />
do !!maze_fac; aMaze := CreateMaze (maze_fac); end<br />
CreateMaze (fac: MAZE_FACTORY_ACCESS): MAZE is<br />
local r1, r2: ROOM; d: DOOR;<br />
do Result := fac.new_maze;<br />
r1 := fac.new_room(1); r2 := fac.new_room(2);<br />
door := fac.new_door(r1,r2);<br />
Result.AddRoom(r1); Result.AddRoom(r2); .....<br />
-- set up r1 and r2<br />
end<br />
end<br />
Universität Rostock, FB Informatik, Lehrstuhl Softwaretechnik Seite 94<br />
16