Kapitel 7 Entwurfsmuster (“Design Patterns”) - SE-Wiki

Werbung
Vorlesung „Softwaretechnologie“
Wintersemester 2010
ROOTS
Kapitel 7
Entwurfsmuster (“Design Patterns”)
Stand: 6.12.2010
30.11.2010: Ergänzt um „Dynamic Proxy Classes“ in Java
06.12.2010: Ergänzt um Hinweisfolie auf Entwurfsmusterbeschreibungen in weiteren Kapiteln
Einführung: Die Grundidee von Pattern
 Grundlegende Idee
 Alle Ingenieurdisziplinen benötigen eine Terminologie ihrer wesentlichen
Konzepte sowie eine Sprache, die diese Konzepte in Beziehung setzt.
 Pattern (Muster) wurden zuerst im Bereich der Architektur beschrieben.
 Ziele von Pattern in der Welt der Software:
 Dokumentation von Lösungen wiederkehrender Probleme, um
Programmierer bei der Softwareentwicklung zu unterstützen.
 Schaffung einer gemeinsamen Sprache, um über Probleme und ihre
Lösungen zu sprechen.
 Bereitstellung eines standardisierten Katalogisierungsschemas um
erfolgreiche Lösungen aufzuzeichnen.
 Bei Pattern handelt es sich weniger um eine Technologie (wie z.B. bei
UML), als um eine Kultur der Dokumentation und Unterstützung guter
Softwarearchitektur.
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-2
ROOTS
Einführung: Literatur zu Pattern und
Software

Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (Gang of Four):
"Design Patterns - Elements of Reusable Object-Oriented Software"
Addison-Wesley, 1995

Frank Buschmann, Regine Meunier, Hans Rohnert, Peter Sommerlad, Michael Stal
(Gang of Five): "Pattern-Oriented Software Architecture - A System of Patterns"
John Wiley & Sons, 1996

Serge Demeyer, Stephane Ducasse, Oscar Nierstrasz:
"Object Oriented Reengineering Patterns", Morgan Kaufman, 2002

Patterns im WWW
 Portland Pattern Repository: http://c2.com/ppr/
 Hillside Group Patterns Library: http://www.hillside.net/patterns/
 Brad Appleton: „Patterns and Software: Essential Concepts and Terminology“
http://www.bradapp.net/docs/patterns-intro.html
 Doug Lea, Patterns-Discussion FAQ, http://gee.oswego.edu/dl/pd-FAQ/pd-FAQ.html
 Buchliste: http://c2.com/cgi/wiki?PatternRelatedBookList
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-3
ROOTS
Einführung: Das MVC-Framework in
Smalltalk als Beispiel
a = 50%
b = 30%
c = 20%
2. Änderungen
am Modell
werden
propagiert
-
Model
-
X
1. Views melden sich an
View + Controller
© 2000-2010 Dr. G. Kniesel
X
a = 50%
b = 30%
c = 20%
View + Controller
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-4
ROOTS
Einführung: Das MVC-Framework in
Smalltalk als Beispiel
Model
a = 50%
b = 30%
c = 20%
-
X
-
X
-
X
a = 50%
b = 30%
c = 20%
View + Controller
View + Controller
Neue Views können ohne Änderung des Modells oder der anderen Views hinzugefügt werden
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-5
ROOTS
Einführung: Das MVC-Framework in
Smalltalk als Beispiel
a = 50%
b = 30%
c = 20%
 Propagierung von Änderungen: Observer Pattern
 Kommt z.B. auch bei Client/Server-Programmierung
zur Benachrichtigung der Clients zum Einsatz
X
-
 Geschachtelte Views: Composite Pattern
-
 View enthält weitere Views, wird aber wie ein
einziger View behandelt.
 Kommt z.B. auch bei Parsebäumen im Compilerbau
zum Einsatz (Ausdrücke).
X
 Reaktion auf Events im Controller: Strategy Pattern
 Eingabedaten können validiert werden
(Daten, Zahlen, etc.).
 Controller können zur Laufzeit gewechselt werden.
 Kommt z.B. auch bei der Codeerzeugung im Compilerbau
zum Einsatz (Code für verschiedene CPUs).
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-6
-
X
ROOTS
Überblick
1.
Einführung
2.
Einstiegsbeispiel: "Observer" im Detail
3.
Was also sind Patterns?
4.
Wichtige Patterns
5.
Zusammenspiel verschiedener Patterns
6.
Fazit: Nutzen von Patterns
7.
Zusammenfassung und Ausblick
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-7
ROOTS
Kapitel 6: Entwurfsmuster
Das Observer Pattern
ROOTS
Das Observer Pattern: Einführung
 Absicht
 Stellt eine 1-zu-n Beziehung zwischen Objekten her
 Wenn das eine Objekt seinen Zustand ändert, werden die davon
abhängigen Objekte benachrichtigt und entsprechend aktualisiert
 Andere Namen
 "Dependents", "Publish-Subscribe", "Listener"
 Motivation
 Verschiedene Objekte sollen zueinander konsistent gehalten werden
 Andererseits sollen sie dennoch nicht eng miteinander gekoppelt sein.
(bessere Wiederverwendbarkeit)
 Diese Ziele stehen in einem gewissen Konflikt zueinander. Man spricht von
„conflicting forces“, also gegenläufig wirkenden Kräften.
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-10
ROOTS
Das Observer Pattern: Beispiel
 Trennung von Daten und Darstellung
 Wenn in einer Sicht Änderungen vorgenommen werden, werden alle
anderen Sichten aktualisiert – Sichten sind aber unabhängig voneinander.
a = 50%
b = 30%
c = 20%
-
X
-
X
-
X
a = 50%
b = 30%
c = 20%
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-11
ROOTS
Das Observer Pattern: Anwendbarkeit
Das Pattern ist im folgenden Kontext anwendbar:
a = 50%
b = 30%
c = 20%
-
 Abhängigkeiten
-
-
a = 50%
b = 30%
c = 20%
 Ein Aspekt einer Abstraktion ist abhängig von einem anderen Aspekt.
 Aufteilung dieser Aspekte in verschiedene Objekte erhöht
Variationsmöglichkeit und Wiederverwendbarkeit.
 Folgeänderungen
 Änderungen an einem Objekt erfordert Änderungen an anderen Objekten.
 Es ist nicht bekannt, wie viele Objekte geändert werden müssen.
 Lose Kopplung
 Objekte sollen andere Objekte benachrichtigen können, ohne Annahmen
über die Beschaffenheit dieser Objekte machen zu müssen.
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-12
ROOTS
Das Observer Pattern: Struktur
(N:1, Pull-Modell)
1
*
<<interface>>
Observer
subject
observers
{abstract}
Subject
observers.add(o)
update() :void
attach(o:Observer):void
detach(o:Observer):void
notify() : void
observers.remove(o)
for all o in observers {
o.update();
}
ConcreteObserver
ConcreteSubject
{redefines subject}
subjectState:State
1
return subjectState;
update() :void
…
subject.getState();
…
subjectState = s;
notify()
getState() : State
setState(State s): void
Rollenaufteilung / Verantwortlichkeiten
(Pull Modell)
 Observer („Beobachter“) -- auch: Subscriber, Listener
 update() -- auch: handleEvent
 Reaktion auf Zustandsänderung des Subjects
 Subject („Subjekt“) -- auch: Publisher
 attach(Observer o) -- auch: register, addListener
 Observer registrieren
 detach(Observer o) -- auch: unregister, removeListener
 registrierte Observer entfernen
 notify()
 update-Methoden aller registrierten Observer aufrufen
 setState(…)
 zustandsändernde Operation(en)
 für internen Gebrauch und beliebige Clients
 getState()
 abfrage des aktuellen Zustands
 damit Observer feststellen können was sich wie geändert hat
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-14
ROOTS
Das Observer Patterns: Implementierung
Wie werden die Informationen über eine Änderung weitergegeben:
„push“ versus „pull“
 Pull: Subjekt übergibt in „update()“ keinerlei Informationen, aber die
Beobachter müssen sich die Informationen vom Subjekt holen
 + Geringere Kopplung zwischen Subjekt und Beobachter.
 – Berechnungen werden häufiger durchgeführt.
 Push: Subjekt übergibt in Parametern von „update()“ detaillierte
Informationen über Änderungen.
 + Rückaufrufe werden seltener durchgeführt.
 – Beobachter sind weniger wiederverwendbar (Abhängig von den
Parametertypen)
 Zwischenformen sind möglich
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-15
ROOTS
Das Observer Pattern: Struktur
(N:1, Push-Modell)
<<interface>>
Observer
1
*
subject
observers
{abstract}
Subject
observers.add(o)
update(StateA) :void
observers.remove(o)
ConcreteObserver
attach(o:Observer):void
detach(o:Observer):void
notify() : void
ConcreteSubject
subjectStateA:StateA
subjectStateB:StateB
update(StateA) :void
for all o in observers {
o.update(subjectStateA);
}
notify() : void
setState(State s): void
Das Observer Pattern: Implementierung
 Vermeidung irrelevanter Notifikationen durch Differenzierung von
Ereignissen
 Bisher: Notifikation bei jeder Änderung
 Alternative: Beobachter-Registrierung und Notifikation nur für spezielle
Ereignisse
 Realisierung: Differenzierung von attach(), detach(), update() und notify() in
jeweils ereignisspezifische Varianten
 Vorteile:
 Notifikation nur für relevante Ereignisse  höhere Effizienz
 Weniger „Rückfragen“ pro Ereignis  höhere Effizienz
 Nachteil: Mehr Programmieraufwand, wenn man sich für viele
Ereignistypen interessiert
 Aber: Werkzeugunterstützung möglich
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-19
ROOTS
Das Observer Patterns: Implementierung
 ChangeManager
 Verwaltet Beziehungen zwischen Subjekt und Beobachter.
(Speicherung in Subjekt und Beobachter kann entfallen.)
 Definiert die Aktualisierungsstrategie
 Benachrichtigt alle Beobachter. Verzögerte Benachrichtigung möglich
 Insbesondere wenn mehrere Subjekte verändert werden müssen, bevor die
Aktualisierungen der Beobachter Sinn macht
 Wer ruft notify() auf?
 a) "setState()"-Methode des Subjekts:
 + Klienten können Aufruf von "notify()" nicht vergessen.
 – Aufeinanderfolgende Aufrufe von "setState()" führen zu evtl. überflüssigen
Aktualisierungen.
 b) Klienten:
 + Mehrere Änderungen können akkumuliert werden.
 – Klienten vergessen möglicherweise Aufruf von "notify()".
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-20
ROOTS
Das Observer Pattern: Implementierung
 Konsistenz-Problem
 Zustand eines Subjekts muss vor Aufruf von "notify()" konsistent sein.
 Vorsicht bei Vererbung bei Aufruf jeglicher geerbter Methoden die
möglicherweise „notify()“ -aufrufen :
public class MySubject extends SubjectSuperclass {
public void doSomething(State newState) {
super.doSomething(newState); // ruft "notify()" auf
this.modifyMyState(newState); // zu spät!
}
}
 Lösung
 Dokumentation von „notify()“-Aufrufen erforderlich (Schnittstelle!)
 Besser: In Oberklasse „Template-Method Pattern“ anwenden um
sicherzustellen, dass „notify()“-Aufrufe immer am Schluss einer Methode
stattfinden  s. nächste Folie.
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-21
ROOTS
Das Observer Pattern: Implementierung
Verwendung des „Template Method Pattern“
Template Method
public class SubjectSuperclass {
...
final public void doSomething(State newState) {
this.doItReally(newState);
this.notify();
// notify immer am Schluß
}
public void doItReally(State newState) {
}
}
Hook Method
public class MySubject extends SubjectSuperclass {
public void doItReally(State newState) {
this.modifyMyState(newState);
}
}
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-22
ROOTS
Kapitel 6: Entwurfsmuster
Konsequenzen von Observer für
Abhängigkeiten
Für Abhängigkeitsreduzierung allgemein
Für Presentation-Application-Data (PAD)
Für Boundary-Controller-Entity (BCE)
Für Model-View-Kontroller (MVC)
PAD versus BCE versus MVC
ROOTS
Abhängigkeiten mit und ohne Observer
Ohne Observer: Abhängigkeit View  Model
 Ein konkretes Model kennt das Interface eines jeden konkreten View
und steuert was genau jeder der Views nach einem update tun soll:
 myGraphView1.setGraph(this.toPieChart()); myGraphView1.draw();
 myGraphView2.setGraph(this.toBarChart()); myGraphView2.draw();
…
 myTextViewN.print(myState.toString());
:TextViewN
GraphView1
GraphView…
GraphViewJ
setGraph(BarChart p)
draw()
TextView1
TextView…
print() TextViewN
print()
print()
…
:GraphView1
:Model
setState(…)
Model
update()
setState(…)
update()
toPieChart()
toBarChart()
toString()
pie=toPieChart()
setGraph(pie)
draw()
s = toString()
print(s)
Abhängigkeiten mit und ohne Observer
Mit Observer: Abhängigkeit View  Model
 Ein konkretes Model kennt nur das abstrakte Observer-Interface
 Ein konkreter View kennt die zustandsabfragenden Methoden des
konkreten Models
 model.getState1();
 model.getState2();
<<interface>>
Observer
1
*
observers
Subject
subject
:Model
:View
attach(this)
attach(o:Observer)
detach(o:Observer)
notify()
update() :void
setState()
for all o in observers {
o.update();
}
notify()
update()
View
Model
{redefines subject}
1
update() :void
subject.getState();
…
subjectState:State
getState() : State
setState(State s)
getState()
Nettoeffekt: Abhängigkeits- und
Kontrollumkehrung
Abhängigkeitsumkehrung
(„Dependency Inversion“)
Kontrollumkehrung
(„Inversion of Control“)
 Ohne Observer
 Ohne Observer
 Abhängigkeit Model  Views
 Mit Observer
 Model steuert alle updates
 Mit Observer
 Abhängigkeit Model  Views
 Jeder View steuert sein
update
Vergleich Ablauf ohne / mit Observer
:TextViewN
…
:GraphView1
:Model
:Model
:View
setState(…)
attach(this)
setState()
update()
pie=toPieChart()
setGraph(pie)
notify()
update()
draw()
getState()
s = toString()
print(s)
Das Observer Pattern: Konsequenzen
 Unabhängigkeit
 Konkrete Beobachter können hinzugefügt werden, ohne konkrete Subjekte
oder andere konkrete Beobachter zu ändern.
 Konkrete Subjekte können unabhängig voneinander und von konkreten
Beobachtern variiert werden.
 Konkrete Subjekte können unabhängig voneinander und von konkreten
Beobachtern wiederverwendet werden.
 „Broadcast“-Nachrichten
 Subjekt benachrichtigt alle angemeldeten Beobachter
 Beobachter entscheiden, ob sie Nachrichten behandeln oder ignorieren
 Unerwartete Aktualisierungen
 Kleine Zustandsänderungen des Subjekts können komplexe Folgen haben.
 Auch uninteressante Zwischenzustände können unnötige Aktualisierungen
auslösen.
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-27
ROOTS
Das Observer Pattern: Bekannte
Anwendungen
 Bekannte Anwendungen
 Model-View-Controller-Framework in Smalltalk
 Java Foundation Classes / Swing
 Oberon System
 Diverse Client/Server-Modelle, z.B. Java RMI
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-28
ROOTS
Kapitel 6: Entwurfsmuster
Was also sind Patterns?
ROOTS
Bestandteile einer Pattern-Beschreibung
 Name(n) des Patterns
 Problem, das vom Pattern gelöst wird
 Anforderungen, die das Pattern beeinflussen
 Kontext, in dem das Pattern angewendet werden kann
 Lösung. Beschreibung, wie das gewünschte Ergebnis erzielt wird
 Varianten der Lösung
 Beispiele der Anwendung der Lösung
 Konsequenzen aus der Anwendung des Patterns
 Bezug zu anderen Patterns
 Bekannte Verwendungen des Patterns
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-35
ROOTS
Bestandteile eines Patterns: Kontext,
Problem, Randbedingungen
 Problem
 Beschreibung des Problems oder der Absicht des Patterns
 Anforderungen (Forces)
 Die relevanten Anforderungen und Einschränkungen, die berücksichtigt
werden müssen.
 Wie diese miteinander interagieren und im Konflikt stehen.
 Die daraus entstehenden Kosten.
 Typischerweise durch ein motivierendes Szenario illustriert.
 Anwendbarkeit (Context) − Applicability
 Die Vorbedingungen unter denen das Pattern benötigt wird.
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-36
ROOTS
Bestandteile eines Patterns: Lösung
Die Lösung (Software Configuration) wird beschrieben durch:
 Rollen
 Funktionen die Programmelemente im Rahmen des Patterns erfüllen.
 Interfaces, Klassen, Methoden, Felder / Assoziationen
 Methodenaufrufe und Feldzugriffe
 Sie werden bei der Implementierung aufg konkrete Programmelemente
abgebildet (‚Player‘)
 Statische + dynamische Beziehungen
 Klassendiagramm, dynamische Diagramme, Text
 Meistens ist das Verständnis des dynamischen Verhaltens entscheidend
 Denken in Objekten (Instanzen) statt Klassen (Typen)!
 Teilnehmer − Participants
 Rollen auf Typebene (Klassen und Interfaces)
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-37
ROOTS
Kapitel 6: Entwurfsmuster
Klassifikation
Danach, was sie modellieren
Danach, wie sie es modellieren
Danach, wo sie meist eingesetzt werden
ROOTS
"Gang of Four"-Patterns: Überblick und
Klassifikation
Verhalten
Struktur
 Visitor
 Composite
 Observer
 Flyweight
 Command
Bisher
 Template Method
 Chain of Responsibility
 Decorator
 State
 Proxy
 Strategy
 Adapter
 Multiple Vererbung
 Bridge
 Facade
Split Objects
 Factory Method
 Prototype
 Abstract Factory
 Singleton
 Builder
Objekt-Erzeugung
Jetzt
Klassifikation: „Was“ und „Wie“
 Verhaltens-Patterns
 Verhalten leicht erweiterbar, komponierbar, dynamisch änderbar oder
explizit manipulierbar machen
Was?
 Struktur-Patterns
 Objekte mit fehlendem Zustand, rekursive Strukturen
 Verschiedenste Formen der Entkopplung (Schnittstelle / Implementierung,
Identität / physikalische Speicherung, ...)
 Erzeugungs-Patterns
 Flexibilität indem die Festlegung von konkret zu erzeugenden Objekte
(new XYZ()) so weit wie möglich verzögert wird und evtl. sogar zur Laufzeit
immer noch verändert werden kann.
Wie?
 Split Object Patterns
 Ziel: Dynamisch änderbares Verhalten, gemeinsame Verwendung oder
Entkopplung von Teilobjekten
 Weg: Aufteilung eines konzeptionellen Gesamtobjektes in modellierte
Teilobjekte die kooperieren um das Verhalten des konzeptionellen
Gesamtobjektes zu realisieren
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-40
ROOTS
Klassifikation: „Was“ und „Wie“
(Fortsetzung)
 Klassifikation danach was modelliert wird (vorherige Folien)
 Struktur, Verhalten, Objekterzeugung
 Klassifikation danach, wie etwas modelliert wird (vorherige Folien)
 Whole Objects: 1:1-Entsprechung von konzeptuellen Objekten und
Implementierungs-Objekten
 Split Objects: Aufteilung eines konzeptuellen Objektes in verschiedene
Implementierungs-Objekte, dynamisch veränderbare Anteile oder
Gemeinsamkeiten verschiedener konzeptueller Objekte darstellen
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-41
ROOTS
Klassifikation: „Wo“
 Klassifikation danach, wo sie meist eingesetzt werden
 Systementwurf, zur Verbindung / Abgrenzung von Subsystemen
 Facade, Adapter, Bridge, Proxy, Singleton (zusammen mit Facade) , Observer
 Objektentwurf
 Observer, Command, Factory Method, Abstract Factory, Composite, Visitor
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-42
ROOTS
Kapitel 6: Entwurfsmuster
Wichtige Entwurfsmuster, Teil 1
- System Design Patterns Facade
Singleton
Adapter
Proxy
Bridge
ROOTS
Kapitel 6: Entwurfsmuster
Das Singleton Pattern
ROOTS
Singleton: Motivation
 Beschränkung der Anzahl von Exemplaren zu einer Klasse
 Meist: nur ein einzelnes Exemplar
 Motivation: Zentrale Kontrolle  Z.B. Facade, Repository, Abstract Factory
 Aber auch: feste Menge von Exemplaren
 Motivation 1: begrenzte Ressourcen (z.B. auf mobilen Geräten)
 Motivation 2: Teure Objekterzeugung durch „Object Pool“ vermeiden
 z.B. 1000 Enterprise Java Beans vorhalten, nach Nutzung zurück in
den Pool
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-46
ROOTS
Singleton: Struktur + Implementierung
Besitzt nur private Konstruktoren:
Singleton
getInstance()
instanceOperation()
-instancePool
-instanceData
private Singleton() {
this.Singleton(arg1, ..., argN);
}
Liefert eine Instanz (typischerweise immer die
private Singleton(...) {
Selbe):
...
}
public static Singleton getInstance() {
if (instancePool == null)
Speichert die einzige
instancePool = new Singleton();
return instancePool;
Instanz oder begrenzte
}
Menge an Instanzen
 Nur private Konstruktoren
 dadurch wird verhindert, dass Clients beliebig viele Instanzen erzeugen
können
 in Java muss explizit ein privater Konstruktor mit leerer Argumentliste
implementiert werden, damit kein impliziter öffentlicher Konstruktor vom
Compiler erzeugt wird
 instancePool als Registry für alle Singleton-Instanzen
 lookup-Mechanismus erforderlich um gezielt eine Instanz auszuwählen
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-47
ROOTS
Kapitel 6: Entwurfsmuster
Das Proxy Pattern
ROOTS
Proxy Pattern (auch: Surogate, Smart
Reference)
 Absicht
 Stellvertreter für ein anderes Objekt
 bietet Kontrolle über Objekt-Erzeugung und -Zugriff
 Motivation
 kostspielige Objekt-Erzeugung verzögern (zB: große Bilder)
 verzögerte Objekterzeugung soll Programmstruktur nicht global verändern
 Idee
 Bild-Stellvertreter (Proxy) verwenden
 Bild-Stellvertreter verhält sich aus Client-Sicht wie Bild
 Bild-Stellvertreter erzeugt Bild bei Bedarf
:TextDocument
image
:ImageProxy
file
:Image
Hauptspeicher
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Platte
Seite 7-52
ROOTS
Proxy Pattern: Beispiel
<<interface>> *
Graphic
DocumentEditor
draw()
getExtent()
store()
load()
Image
<<creates>>
fileName
extent
imageData
extent
draw()
getExtent()
store()
load()
© 2000-2010 Dr. G. Kniesel
ImageProxy
image
draw()
getExtent()
store()
load()
Vorlesung „Softwaretechnologie“ (SWT)
if (image == 0){
image = loadImage(filename);
}
image.draw()
if (image == 0){
return extent;
} else {
return image.getExtent();
}
Seite 7-53
ROOTS
Proxy Pattern: Schema
<<interface>> *
Client
Subject
request()
...
RealSubject
realSubject
Proxy
request()
...
request()
...
:RealSubject
:Proxy
 request()
© 2000-2010 Dr. G. Kniesel
...
realSubject.request();
...
 request()
Vorlesung „Softwaretechnologie“ (SWT)
:Client
Seite 7-54
ROOTS
Proxy Pattern: Verantwortlichkeiten
 Proxy
 bietet gleiches Interface wie "Subject"
 referenziert eine "RealSubject"-Instanz
 kontrolliert alle Aktionen auf dem "RealSubject"
 Subject
 definiert das gemeinsame Interface
 RealSubject
 das Objekt das der Proxy vertritt
 eigentliche Funktionalität
 Zusammenspiel
 selektives Forwarding
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-55
ROOTS
Proxy Pattern: Anwendbarkeit
 Virtueller Proxy
 verzögerte Erzeugung "teurer" Objekte bei Bedarf
 Beispiel: Bilder in Dokument, persistente Objekte
 Remote Proxy
 Zugriff auf entferntes Objekt
 Objekt-Migration
 Beispiele: CORBA, RMI, mobile Agenten
 Concurrency Proxy
 nur eine direkte Referenz auf RealSubject
 locking des RealSubjects vor Zugriff (threads)
 Copy-on-Write
 kopieren erhöht nur internen "CopyCounter"
 wirkliche Kopie bei Schreibzugriff und "CopyCounter">0
 Verzögerung teurer Kopier-Operationen
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-56
ROOTS
Proxy Pattern: Anwendbarkeit
 Protection Proxy (Zugriffskontrolle)
 Schmaleres Interface
 "Kritische" Operationen ausgeblendet
 andere via Forwarding implementiert
 ganz anderes Interface
 Autorisierung prüfen
 direkten Zugriff gewähren oder Forwarding
 Beispiel: "CHOICES" Betriebssystem, JDK
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-57
ROOTS
Protection-Proxy im JDK (ab 1.2):
GuardedObject

Problem
 Sichere Weitergabe eines schützenwerten Objektes an unbekannten Empfänger
 Objektspezifische Zugriffsrechte
 Verzögerte Überprüfung der Zugriffsrechte

Idee: GuardedObject
 Enthält "bewachtes Objekt" und "Wächter" (Guard)
 Guard-Interface enthält nur die Methode checkGuard(Object)
 Referenz auf bewachtes Objekt wird nur dann herausgegeben, wenn
checkGuard(Object)erfolgreich ist (sonst SecurityException)
checkGuard(...)
requestor : Object
getObject()
: Guard
proxy : GuardedObject
guarded
: Object

Verbleibendes Problem
 Man muß sich darauf verlassen, daß der "Requestor" das "bewachte
Objekt" selbst nur in ein GuardedObject verpackt weitergibt!
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-58
ROOTS
Proxy Pattern: Implementierung
 „Consultation“ = Weiterleiten von Anfragen
 Allgemein: manuell erstellte Forwarding-Methoden
 C++: Operator-Overloading
 Proxy redefiniert Dereferenzierungs-Operator:*anImage
 Proxy redefiniert Member-Accesss-Operator:anImage->extent()
 Smalltalk: Reflektion
 Proxy redefiniert Methode "doesNotUnderstand: aMessage"
 Lava: eigenes Sprachkonstrukt
 Proxy deklariert "consultee"-Variable
class Proxy {
private consultee RealImage realImage;
...
}
 Falls der Typ von "RealSubject„ dem Proxy bekannt sein muß:
 Je eine spezifische Proxy-Klasse für jeden RealSubject-Typ
 ... dem Proxy nicht bekannt sein muß:
 Nur eine Proxy-Klasse für verschiedene RealSubject-Typen
 Beispiel: „Guarded Object“ (vorherige Folie)
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-59
ROOTS
Proxy Pattern: Implementierung mit
„Dynamic Proxies“ in Java
 Problem: Herkömliche Proxies, mit vielen für den „Subject“-Type
spezifischen Weiterleitungsmethoden zu schreiben ist aufwendig und
wartungsintensiv
 Wunsch: Nur eine Proxy-Klasse und nur eine Weiterleitungs-Methode
für beliebige „Subject“-Typen an die weitergeleitet wird
 Nutzen
 Generische Anfrageweiterleitung
 Dynamische Erstellung von Stellvertretern für entfernte Objekte
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-60
ROOTS
Proxy Pattern: Implementierung mit
„Dynamic Proxies“ in Java
 Eine Dynamic Proxy Class ist eine zur Laufzeit erzeugte Klasse, die
eine bei ihrer Erzeugung angegebene Liste von Interfaces
implementiert
Methode in
// Creates a proxy class and an instance of the proxy:
java.lang.reflect.Proxy
public static Object newProxyInstance(
ClassLoader loader,
Class[] interfaces,
InvocationHandler handler) throws IllegalArgumentException
 Jede ihrer Instanzen aggregiert ein Objekt dessen Klasse das
Interface InvocationHandler implementiert
 Jeder Aufruf an die Proxy-Instanz wird (automatisch) per Reflektion
explizit als Objekt dargestellt und an die invoke()-Method des
zugehörigen InvocationHandler übergeben.
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-61
ROOTS
Proxy Pattern: Implementierung mit
„Dynamic Proxies“ in Java
API und Tutorials
 Official JDK API: "Dynamic Proxy Classes"
http://download.oracle.com/javase/1.3/docs/guide/reflection/proxy.html
 Brian Goetz:
"Java theory and practice: Decorating with dynamic proxies",
http://www.ibm.com/developerworks/java/library/j-jtp08305.html
 Bob Tarr:
"Dynamic Proxies In Java",
http://userpages.umbc.edu/~tarr/dp/lectures/DynProxies-2pp.pdf
 Mark Davidson:
"Using Dynamic Proxies to Generate Event Listeners Dynamically"
http://java.sun.com/products/jfc/tsc/articles/generic-listener2/index.html
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-62
ROOTS
Proxy Pattern: Implementierung
 Refenrenzierung des RealSubject vor Instantiierung
 Orts- und Zeit-unabhängige "Ersatz-Referenzen"
 Beispiele
 Dateinamen
 CORBA IOR (Interoperable Object Reference)
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-63
ROOTS
Kapitel 6: Entwurfsmuster
Das Adapter Pattern
ROOTS
Adapter Pattern (auch: Wrapper)
 Absicht
 Schnittstelle existierender Klasse an Bedarf existierender Clients anpassen
 Motivation
 Graphik-Editor bearbeitet Shapes
 Linien, Rechtecke, ...
 durch "BoundingBox" beschrieben
 Textelemente sollen auch möglich sein
 Klasse TextView vorhanden
 bietet keine "BoundingBox"-Operation
 Integration ohne
 Änderung der gesamten Shape-Hierarchie und ihrer Clients
 Änderung der TextView-Klasse
 Idee
 Adapter-Klasse stellt Shape-Interface zur Verfügung
 ... implementiert Shape-Interface anhand der verfügbaren TextViewMethoden
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-65
ROOTS
Adapter Pattern: Beispiel
Existierende Klassen
DrawingEditor
*
Shape
Adapter-Klasse
BoundingBox()
CreateManipulator()
Line
TextShape
BoundingBox()
CreateManipulator()
BoundingBox()
CreateManipulator()
text
TextView
getExtent()
...
return text.getExtent()
return new TextManipulator()
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-66
ROOTS
Adapter Pattern (Objekt-Adapter):
Schema
adaptee
Client
Target
Adaptee
request()
other()
f()
f()
Adaptee_N
…
Adapter
request()
f()
:Client
…
adaptee.other()
:Adapter
request()
:Adaptee_N
other()
f()
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-67
ROOTS
Adapter Pattern (Objekt-Adapter):
Konsequenzen
adaptee
Client
Target
Adaptee
request()
other()
f()
f()
Adaptee_N
…
Adapter
request()
f()
…
adaptee.other()
 Adaptiert eine ganze Klassenhierarchie
 Beliebige Adapter-Subtypen können mit beliebigen Adaptee-Subtypen
kombiniert werden ( siehe Objektdiagram auf vorheriger Folie)
 Kombination wird erst zur Laufzeit, auf Objektebene, festgelegt
 Overriding nicht möglich
 Die f()-Definition aus Adapter wird nicht anstelle der f()-Definition aus
Adaptee für den f()-Aufruf aus der Methode other() verwendet
( siehe Objektdiagram auf vorheriger Folie)
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-68
ROOTS
Adapter Pattern (Object Adapter):
Variante
Client
Target
request()
Adapter
adaptee
Adaptee
other()
f()
f()
…
Adaptee_N
…
…‘
Adaptee_N‘
…‘
f()
f()
f()
request()
f()
 Object Adapter mit Overriding
 zu Adaptee und jede Unterklasse des Adaptees eine weitere Unterklasse
einfügen, in die das redefinierte Verhalten eingefügt wird (also z.B. f())
 Warum neue Unterklassen? Weil die vorhandene Adaptee-Hierarchie nicht
veränderbar ist!
 Problem: Redundanz!
 Was konzeptionell nur ein mal in „Adapter“ stehen sollte wird in jeder neuen
Unterklasse von „Adaptee“ redundant eingefügt  Wartungsprobleme!
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-69
ROOTS
Class Adapter Idiom
„Vererbung ohne Subtyping“:
Erbender erbt Methoden die nicht als
Teil seines Interface sichtbar werden.
 "private inheritance" in C++
 "closed inheritance" in Eiffel
Client
Target
Adaptee
request()
other()
f()
f()
Adaptee_N
…
<<implementation inheritance>>
Adapter
request()
f()
:Client
…
anAdaptedAdaptee:Adapter
request()
other()
f()
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-70
ROOTS
Class Adapter Idiom: Konsequenzen
Client
Target
Adaptee
request()
other()
f()
f()
Adaptee_N
…
<<implementation inheritance>>
Adapter
request()
f()
:Client
…
anAdaptedAdaptee:Adapter
 Overriding des Adaptee-Verhaltens leicht möglich
 Da Adapter eine Unterklasse von Adaptee ist, funktioniert das Overriding von
f()
 Keine zusätzliche Indirektion
 nur ein Objekt statt zwei
 Adaptiert nur eine Klasse
 Die gelben Unterklassen von Adaptee werden nicht mit adaptiert
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-71
ROOTS
Adapter Pattern: Konsequenzen
 Class Adapter
Client
 adaptiert nur eine Klasse
 ... nicht ihre Unterklassen
 Overriding des Adaptee-Verhaltens leicht möglich
 keine zusätzliche Indirektion (nur ein Objekt)
 Object Adapter
 adaptiert eine ganze Klassenhierarchie
 Overriding schwieriger
:Client
Target
request()
Adapter
request()
Adaptee
f()
m()
Adapt_N
f()
m()
:Adapter
:Adaptee
 redefiniertes Verhalten in spezifische Unterklasse des Adaptees einfügen
 Adapter benutzt diese Unterklasse
 Kombinierbarkeit mit anderen Unterklassen geht verloren
 Object Adapter mit Delegation (roots.iai.uni-bonn.de/research/darwin)
 adaptiert eine ganze Klassenhierarchie
 Overriding des Adaptee-Verhaltens leicht möglich
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-72
ROOTS
Kapitel 6: Entwurfsmuster
Das Bridge Pattern
ROOTS
Bridge Pattern (auch: Handle / Body)
 Absicht
 Schnittstelle und Implementierung trennen
 ... unabhängig variieren
 Motivation
 portable "Window"-Abstraktion in GUI-Toolkit
 mehrere Variations-Dimensionen
 Fenster-Arten:
– normal / als Icon,
– schließbar / nicht schließbar,
– ...
 Implementierungen:
–
–
–
–
–
© 2000-2010 Dr. G. Kniesel
X-Windows,
IBM Presentation Manager,
MacOS,
Windows XYZ,
...
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-84
ROOTS
Bridge Pattern: Warum nicht einfach Vererbung
einsetzen?
Neue Fenster-Art:
"iconifizierbare" Fenster
Window
XWindow
PMWindow
Window
XWindow
 Probleme dieses Lösungsversuchs
PMWindow
IconWindow
XIconWindow
PMIconWindow
 Eigene Klasse für jede Kombination Fenster-Art / Plattform
 unwartbar
 Client wählt Kombination Fenster-Art / Plattform (bei der Objekterzeugung)
 plattformabhängiger Client-Code
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-85
ROOTS
Bridge Pattern: Idee
 Trennung von
 Konzeptueller Hierarchie
 Implementierungs-Hierarchie
bridge
imp
Window
WindowImp
drawText()
drawRect()
devDrawText()
devDrawLine()
imp.devDrawLine()
imp.devDrawLine()
imp.devDrawLine()
imp.devDrawLine()
IconWindow
TransientWindow
XWindowImp
PMWindowImp
drawBorder()
drawCloseBox()
devDrawText()
devDrawLine()
devDrawLine()
devDrawText()
XDrawLine()
XDrawString()
drawRect()
drawText()
drawRect()
Bridge Pattern: Schema
Client
Abstraction
imp
Implementor
operation()
basicOperation()
imp.basicOperation()
RefinedAbstraction
© 2000-2010 Dr. G. Kniesel
ConcreteImplementorA
ConcreteImplementorB
basicOperation()
basicOperation()
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-87
ROOTS
Bridge Pattern: Anwendbarkeit
 Dynamische Änderbarkeit
 Implementierung erst zur Laufzeit auswählen
 Unabhängige Variabilität
 neue Unterklassen in beiden Hierarchien beliebig kombinierbar
 Implementierungs-Transparenz für Clients
 Änderungen der Implementierung erfordern keine Änderung /
Neuübersetzung der Clients
 Vermeidung von "Nested Generalisations"
 keine Hierarchien der Art wie in der Motivations-Folie gezeigt
 keine kombinatorische Explosion der Klassenanzahl
 Sharing
 mehrere Clients nutzen gleiche Implementierung
 z.B. Strings
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-89
ROOTS
Bridge Pattern: Implementierung
Client
Abstraction
Implementor
imp
Instantiierung des richtigen ConcreteImplementors
...
 Falls Abstraction alle ConcreteImplementor-Klassen kennt:
 Fallunterscheidung im Konstruktor der ConcreteAbstraction
 Auswahl des ConcreteImplementor anhand von Parametern des
Konstruktors
 Alternativ: Default-Initialisierung und spätere situationsbedingte Änderung
 Falls Abstraction völlig unabhängig von ConcreteImplementor-Klassen
sein soll:
 Entscheidung anderem Objekt überlassen
 Abstract Factory Pattern
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-90
ROOTS
Kapitel 6: Entwurfsmuster
Wichtige Entwurfsmuster, Teil 2
- Object Design Patterns Command
Factory Method
Abstract Factory
Composite
Visitor
ROOTS
"Gang of Four"-Patterns: Überblick und
Klassifikation
Verhalten
 Visitor
Struktur
 Composite
 Observer
 Flyweight
 Command
 Template Method
 Chain of Responsibility
 Decorator
 State
 Proxy
 Strategy
 Adapter
 Multiple Vererbung
 Bridge
 Facade
Jetzt
Split Objects
 Factory Method
 Prototype
 Abstract Factory
 Singleton
 Builder
Objekt-Erzeugung
Kapitel 6: Entwurfsmuster
Das Factory Method Pattern
ROOTS
Factory Method
 Ziel
 Entscheidung über konkreter Klasse neuer Objekte verzögern
 Motivation
 Framework mit vordefinierten Klassen "Document" und "Application"
 Template-Methode, für das Öffnen eines Dokuments:
 1. Check ob Dokument-Art bekannt
 2. Erzeugung einer Document-Instanz !?!
 Erzeugung von Instanzen noch nicht bekannter Klassen!
 Idee
 aktuelle Klasse entscheidet wann Objekte erzeugt werden
 Aufruf einer abstrakten Methode
 Subklasse entscheidet was für Objekte erzeugt werden
 implementiert abstrakte Methode passend
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-94
ROOTS
Factory Method: Beispiel
Framework
Document
MyDocument
*
docs
Application
newDocument()
doCreateDocument()
Document doc = doCreateDocument();
docs.add(doc);
doc.open();
MyApplication
doCreateDocument()
Applikation
return new MyDocument()
Factory Method: Schema
Creator
Product
anOperation()
factoryMethod()
ConcreteProduct
...
product = factoryMethod();
...
ConcreteCreator
factoryMethod()
return new ConcreteProduct()
 Factory Method
 kann abstrakt sein
 kann Default-Implementierung haben
 Creator (Aufrufer der Factory Method)
 kann Klasse sein, die die Factory Method definiert
 kann Client-Klasse sein
 Beispiel: parallele Vererbungs-Hierarchien
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-96
ROOTS
Factory Method: Anwendbarkeit
 Klasse neuer Objekte unbekannt
 Verzögerte Entscheidung über Instantiierung
 erst in Subklasse
 erst beim Client
 Mehrere Hilfsklassen
 Wissen über konkrete Hilfsklassen an einer Stelle lokalisieren
 Beispiel: Parallele Hierarchien (nächste Folie)
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-97
ROOTS
Factory Method: Anwendbarkeit
Figure
Client
Manipulator
createManipulator()
...
downClick()
drag()
upClick()
LineFigure
TextFigure
createManipulator()
...
createManipulator()
...
LineManipulator
Textmanipulator
downClick()
drag()
upClick()
downClick()
drag()
upClick()
 Verbindung paralleler Klassenhierarchien
 Factory Method lokalisiert das Wissen über zusammengehörige Klassen
 Restlicher Code der Figure-Hierarchie und Client-Code ist völlig
unabhängig von spezifischen Manipulators (nur vom Manipulator-Interface)
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-98
ROOTS
Factory Method: Implementierung
 Fester "Produkt-Typ"
 jede Unterklasse erzeugt
festgelegte Produkt-Art
 Codierter "Produkt-Typ"
 Parameter oder Objekt-Variable
kodiert "Produkt-Typ"
 Fallunterscheidung anhand
Code
 mehrere Produkte
 mehr Flexibilität
 Klassen-Objekt als "Produkt-Typ"
 Parameter oder Objekt-Variable
ist "Produkt-Typ"
 direkte Instantiierung
 mehr Flexibilität
 bessere Wartbarkeit
 kein statischer Typ-Check
© 2000-2010 Dr. G. Kniesel
class Creator {
Product create(){ MyProduct(); }
}
class Creator {
Product create(int id) {
if (id==1) return MyProduct1();
if (id==2) return MyProduct2();
...
}
}
Idiom reflektiver Sprachen
• Smalltalk
• Java
class Creator {
Object create(Class prodType) {
return prodType.getInstance();
}
}
Reflektiver Aufruf des parameterelosen
Vorlesung „Softwaretechnologie“ (SWT)
Default-Konstruktors
Seite 7-99
ROOTS
Factory Method: Konsequenzen
 Code wird abstrakter / wiederverwendbarer
 keine festen Abhängigkeiten von spezifischen Klassen
 Verbindung paralleler Klassenhierarchien
 Factory Method lokalisiert das Wissen über Zusammengehörigkeiten
 evtl. künstliche Subklassen
 nur zwecks Objekterzeugung
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-100
ROOTS
Factory Method: Anwendungen
 überall in Toolkits, Frameworks, Class Libraries
 Unidraw: Beispiel "Figure und Manipulator"
 MacApp und ET++: Beispiel "Document und Application"
 Smalltalk's Model-View-Controller Framework
 FactoryMethoden-Template: defaultController
 Hook-Methode: defaultControllerClass
 Orbix
 Erzeugung des richtigen Proxy
 leichte Ersetzung von Standard-Proxy durch Caching Proxy
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-101
ROOTS
Kapitel 6: Entwurfsmuster
Das Abstract Factory Pattern
ROOTS
Abstract Factory
 Ziel
 zusammengehörige Objekte verwandter Typen erzeugen
 ... ohne deren Klassenzugehörigkeit fest zu codieren
 Motivation
 GUI-Toolkit für mehrere Plattformen
 Anwendungsklassen nicht von plattformspezifischen Widgets abhängig
machen
 Trotzdem soll die Anwendung
 alle Widgets konsistent zu einem "look and feel" erzeugen können
 "look and feel" umschalten können
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-103
ROOTS
Abstract Factory: Beispiel
WidgetFactory
Client
createWindow()
createScrollBar()
Window
MotifWidgetFactory
createWindow()
createScrollBar()
PMWidgetFactory
PMWindow
MotifWindow
createWindow()
createScrollBar()
Scrollbar
PMScrollbar
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
MotifScrollBar
Seite 7-104
ROOTS
Abstract Factory: Schema
AbstractFactory
Client
createProductA()
createProductB()
AbstractProductA
ConreteFactory1
createProductA()
createProductB()
ConreteFactory2
ProductA2
ProductA1
createProductA()
createProductB()
AbstractProductB
ProductB2
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
ProductB1
Seite 7-105
ROOTS
Abstract Factory: Implementierung
 ConcreteFactories sind Singletons
 Produkt-Erzeugung via Factory-Methods
 fester Produkt-Typ (eine Methode für jedes Produkt)
 Nachteil
 neues Produkt erfordert Änderung der gesamten Factory-Hierarchie
 Codierter "Produkt-Typ" (eine parametrisierte Methode für alle
Produkte)
 Vorteil
 leichte Erweiterbarkeit um neues Produkt
 Nachteile:
 alle Produkte müssen gemeinsamen Obertyp haben
 Clients können nur die Operationen des gemeinsamen Obertyps nutzen
 Verzicht auf statische Typsicherheit
 Klassen-Objekt als "Produkt-Typ" (eine parametrisierte Methode)
 Vorteil
 neues Produkt erfordert keinerlei Änderungen der Factory
 Nachteil
 Verzicht auf jegliche statische Typinformation / Typsicherheit
Abstract Factory: Implementierung
 Produktfamilie = Subklasse
 Vorteil
 Konsistenz der Produkte
 Nachteil
 neue Produktfamilie erfordert neue Subklasse, auch bei geringen
Unterschieden
 Produktfamilie = von Clients konfigurierte assoziative Datenstruktur
 Varianten
 Prototypen und Cloning
 Klassen und Instantiierung
 Vorteil
 keine Subklassenbildung erforderlich
 Nachteil
 Verantwortlichkeit an Clients abgegeben
 konsistente Produktfamilien können nicht mehr garantiert werden
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-107
ROOTS
Abstract Factory: Konsequenzen
 Abschirmung von Implementierungs-Klassen
 Namen von Implementierungsklassen erscheinen nicht im Code von
Clients
 Clients benutzen nur abstraktes Interface
 Leichte Austauschbarkeit von Produktfamilien
 Name einer ConcreteFactory erscheint nur ein mal im Code
 bei ihrer Instantiierung
 Leicht austauschbar gegen andere ConcreteFactory
 Beispiel: Dynamisches Ändern des look-and-feel
 andere ConcreteFactory instantiieren
 alle GUI-Objekte neu erzeugen
 Konsistente Benutzung von Produktfamilien
 Keine Motif-Scrollbar in Macintosh-Fenster
 Schwierige Erweiterung um neue Produktarten
 Schnittstelle der AbstractFactory legt Produktarten fest
 Neue Produktart = Änderung der gesamten Factory-Hierarchie
Abstract Factory: Anwendbarkeit
 System soll unabhängig sein von
 Objekt-Erzeugung
 Objekt-Komposition
 Objekt-Darstellung
 System soll konfigurierbar sein
 Auswahl aus verschiedenen Produkt-Familien
 konsistente Produktfamilien
 nur Objekte der gleichen Familie "passen zusammen"
 Library mit Produktfamilie anbieten
 Clients sollen nur Schnittstelle kennen
 ... nicht die genauen Teilprodukt-Arten / -Implementierungen
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-109
ROOTS
"Gang of Four"-Patterns: Überblick und
Klassifikation
Jetzt
Verhalten
 Visitor
Struktur
 Composite
 Observer
 Flyweight
 Command
 Template Method
 Chain of Responsibility
 Decorator
 State
 Proxy
 Strategy
 Adapter
 Multiple Vererbung
 Bridge
 Facade
Split Objects
 Factory Method
 Prototype
 Abstract Factory
 Singleton
 Builder
Objekt-Erzeugung
Kapitel 6: Entwurfsmuster
Das Command Pattern
ROOTS
Das Command Pattern: Motivation
 Kontext
 GUI-Toolkits mit
Buttons, Menüs, etc.
 Forces
 Vielfalt trotz Einheitlichkeit
 Einheitlicher Code in allen GUI-Elementen
 .. trotzdem verschiedene Effekte
 Wiederverwendung
 Über verschiedene GUI-Elemente ansprechbare Operationen nur ein mal
programmieren
 Dynamik
 dynamische Änderung der Aktionen von Menu-Einträgen
 kontext-sensitive Aktionen
Das Command Pattern: Idee
 Operationen als Objekte mit Methode execute() darstellen
 In den GUI-Elementen speichern
Einheitlicher Aufruf
Application
Menu
MenuItem
add(Document)
add(Menuitem)
clicked()
command.execute();
command
Command
execute()
Document
open()
close()
cut()
copy()
paste()
document
PasteCommand
execute()
document.paste();
Verschiedene
Implementierungen
Command Pattern: Schema und Rollen
setCommand()
Command
execute()
Receiver
ConcreteCommand
action()
execute()
 Command Interface
 Schnittstelle, die festlegt, was
Commands tun können
 Mindestens Execute, optional auch
Undo, Redo
 Concrete Command
 Implementiert Command Interface
 „Controllers“ sind oft
„ConcreteCommands“
<<interface>>
Invoker
Client
 Execute-Methode
 Ausführen von Kommandos
 Undo-Methode
 Rückgängig machen von
Kommandos
 Redo-Methode
 Rückgängig gemachtes Kommando
wieder ausführen
Das Command Pattern: Konsequenzen
 Entkopplung
 von Aufruf einer Operation und Spezifikation einer Operation.
 Kommandos als Objekte
 Command-Objekte können wie andere Objekte auch manipuliert und
erweitert werden.
 Komposition
 Folgen von Command-Objekte können zu weiteren Command-Objekten
zusammengefasst werden.
 Erweiterbarkeit
 Neue Command-Objekte können leicht hinzugefügt werden, da keine
Klassen geändert werden müssen.
Das Command Pattern: Anwendbarkeit
 Operationen als Parameter
 Variable Aktionen
 referenziertes Command-Objekt austauschen
 Zeitliche Trennung
 Befehl zur Ausführung, Protokollierung, Ausführung
 Speicherung und Protokollierung von Operationen
 History-Liste
 Serialisierung
 "Undo" von Operationen
 Command-Objekte enthalten neben execute() auch unexecute()
 werden in einer History-Liste gespeichert
 Recover-Funktion nach Systemabstürzen
 History-Liste wird gespeichert
 Zustand eines Systems ab letzter Speicherung wiederstellbar
 Unterstützung von Transaktionen
 Transaktionen können sowohl einfache ("primitive"), als auch komplexe CommandObjekte sein.
Implementierung des Command Patterns
 Unterschiedliche Grade von Intelligenz
 Command-Objekte können "nur" Verbindung zwischen Sender und Empfänger sein,
oder aber alles selbstständig erledigen.
 Unterstützung von "undo"
 Semantik

Undo (unexecute()) und redo (execute()) müssen den exakt gegenteiligen Effekt haben!
 Problem: In den wenigsten Fällen gibt es exact inverse Operationen

Die Mathematik ist da eine Ausnahme...
 Daher Zusatzinfos erforderlich

Damit ein Command-Objekt "undo" unterstützen kann, müssen evtl. zusätzliche
Informationen gespeichert werden.

Typischerweise: Kopien des alten Zustands der Objekte die wiederhergestellt werden
sollen.
 History-Liste

Für mehrere Levels von undo/redo
 Klonen vor Speicherung in der History-Liste

Es reicht nicht eine Referenz auf die Objekte zu setzen!

Man muss das Objekt "tief" klonen, um sicherzustellen dass sein Zustand nicht verändert
wird.
Patterns-Überblick
Verhalten
Struktur
 Visitor
 Composite
 Observer
 Flyweight
 Command
 Template Method
 Chain of Responsibility
 Decorator
 State
 Adapter
 Strategy
 Proxy
 Multiple Vererbung
 Bridge
 Facade
Split Objects
 Factory Method
 Prototype
 Abstract Factory
 Singleton
 Builder
Objekt-Erzeugung
Kapitel 6: Entwurfsmuster
Verbindung von Command und
Observer im JDK
ROOTS
Verbindung von Observer und Command
in Java
<<interface>>
ActionListener
void actionPerfomed(ActionEvent evt)
<<implements>>
MyPasteCommand
:MenuItem
void actionPerfomed(ActionEvent evt)
:Button
 addActionListener(ActionListener)
:JComponent

 actionPerformed(ActionEvent)
: MyPasteCommand
 registerKeyboardAction(ActionListener, KeyStroke, ...)
Observer
 Buttons, Menue-Einträge und Tasten
generieren "ActionEvents"
 Interface "ActionListener" ist vordefiniert
 "ActionListener" implementieren
 ... und Instanzen davon bei Buttons,
MenuItems, etc registrieren

Command & Observer
 gleiche Methode (z.B. actionPerformed)
spielt die Rolle der run() Methode eines
Commands und die Rolle der update()
Methode eines Observers
 implementierende Klasse (z.B.
MyPasteCommand) ist gleichzeitig ein
Command und ein Observer
Verbindung von Observer und Command
in Java verbindet auch Push und Pull
<<interface>>
ActionListener
void actionPerfomed(ActionEvent evt)
<<implements>>
MyPasteCommand
:MenuItem
void actionPerfomed(ActionEvent evt)
:Button
 addActionListener(ActionListener)
:JComponent

 actionPerformed(ActionEvent)
: MyPasteCommand
 registerKeyboardAction(ActionListener, KeyStroke, ...)
Push Observer
 Subject „pushed“ eine „Event“-Instanz
 Der „Event“-Typ kann selbst definiert
werden
 In dieser Instanz können somit weitere
Informationen mit „gepushed“ werden
(als Werte von Instanzvariablen)

Pull Observer
 Die als Parameter übergebene
„Event“-Instanz enthält immer eine
Referenz auf die Quelle des Events
 Somit ist es möglich von dort weitere
Informationen zu anzufragen („pull“)
Verbindung von Observer und Command
in Java (2)
 Zusätzliche Unterstützung für
<<interface>>
ActionListener
"Command"
Aktivierung /
Deaktivierung
von
MenuItems
denen diese
"Action"
zugeordnet
ist
... Parameter
können
allerdings
auch direkt als
InstanzVariablen
realisiert
werden.
void actionPerfomed(ActionEvent evt)
<<extends>>
<<interface>>
Action
void putValue(String key, Object value)
Object getValue(String key)
Einheitliche Schnittstelle zur
Speicherung von Parametern
für "Action" ...
boolean isEnabled()
void setEnabled(boolean b)
void addPropertyChangeListener(PropertyChangeListener listener)
void removePropertyChangeListener(PropertyChangeListener listener)
<<implements>>
AbstractAction
// alles ausser void actionPerfomed(ActionEvent evt)
<<extends>>
MyPasteCommand
void actionPerfomed(ActionEvent evt)
im JDK enthalten
 Interface "Action" und Klasse
"AbstractAction"
Beispiel: Änderung der Hintergrundfarbe
(1)
class ColorAction extends AbstractAction
{ public ColorAction(..., Color c, Component comp)
{ ...
color = c;
target = comp;
}
public void actionPerformed(ActionEvent evt)
{ target.setBackground(color);
target.repaint();
}
private Component target;
private Color color;
}
 ColorAction
class ActionButton extends JButton
{ public ActionButton(Action a)
{ ...
addActionListener(a);
}
}
 Ändern der Hintergrundfarbe einer GUI-Komponente
 ActionButton
 Buttons die sofort bei Erzeugung mit einer Action verknüpft werden
Beispiel: Änderung der Hintergrundfarbe
(2)
 Nutzung der ColorAction
 Erzeugung einer Instanz
 Registrierung
class SeparateGUIFrame extends JFrame
{ public SeparateGUIFrame()
{ ...
JPanel panel = new JPanel();
Action blueAction = new ColorAction("Blue", ...,..., panel);
panel.registerKeyboardAction(blueAction,...);
panel.add(new ActionButton(blueAction));
JMenu menu = new JMenu("Color");
menu.add(blueAction);
...
}
}
Beispiel und Erläuterung siehe: "Core Java 2", Kapitel 8,
Abschnitt "Separating GUI and Application Code".
Fazit
 Elegante Verbindung von Observer und Command
 Commands sind ActionListener von Buttons, Menus, etc.
 Einheitlicher Aufru via actionPerformed(ActionEvent evt)
 Buttons und Menus sind PropertyChangeListener von Commands
 Aktivierung / Deaktivierung
 Wiederverwendung
 gleiche Action für Menu, Button, Key
 Dynamik
 Wie ändert man die aktuelle Aktion?
 ... konsistent für alle betroffenen MenuItems, Buttons, etc.???
 Strategy Pattern!
Kapitel 6: Entwurfsmuster
Das Composite Pattern
ROOTS
Composite Pattern
 Ziel
 rekursive Aggregations-Strukturen darstellen ("ist Teil von")
 Aggregat und Teile einheitlich behandeln
 Motivation
 Gruppierung von Graphiken
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-128
ROOTS
Composite Pattern: Beispiel
Graphic
draw()
add(Graphic)
remove(Graphic)
getChildren()
children
Line
Text
Picture
draw()
draw()
draw()
add(Graphic)
remove(Graphic)
getChildren()
:Line
:Text
:Text
:Picture
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
draw() {
for all c in children
c.draw()
}
:Picture
Seite 7-129
ROOTS
Composite Pattern: Struktur
*
Client
Component
operation()
add(Component)
remove(Component)
getChildren()
children
Leaf
Composite
operation()
add(Component)
remove(Component)
getChildren()
operation()
add(Component)
remove(Component)
getChildren()
operation() {
for all c in children
c.operation()
}
add() {}
oder
add() {throw new MessageNotSupportedException()}
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-130
ROOTS
Composite Pattern: Verantwortlichkeiten
*
Component
 Component (Graphic)
operation()
add(Component)
remove(Component)
getChildren()
 gemeinsames Interface aller Teilobjekte
 default-Verhalten
 Interface für Zugriff auf Teilobjekte (!)
children
 evtl. Interface für Zugriff auf Elternobjekte
 Leaf (Rectangle, Line, Text)
Leaf
Composite
 "primitive" Teil-Objekte
operation()
operation()
add(Component)
remove(Component)
getChildren()
 implementieren gemeinsames Interface
 leere Implementierungen für Teilzugriffs-Interface
 Composite (Picture)
 speichert Teilobjekte
 implementiert gemeinsames Interface durch forwarding
 implementiert Teilzugriffs-Interface
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-131
ROOTS
Composite Pattern: Implementierung
 Wenn Composites wissen sollen wovon sie Teil sind
*
Component
operation()
add(Component)
remove(Component)
getChildren()
 Explizite Referenzen auf Composite in
Component Klasse
children
 Schließt explizite Referenz der Components
1
gemeinsam nutzen sollen
parent
 Wenn mehrere Composites Components
Leaf
Composite
operation()
operation()
add(Component)
remove(Component)
getChildren()
auf Composite aus oder erfordert, dass Components
wissen, dass sie Teile mehrerer Composites sind
 Component Interface
 "Sauberes Design": Verwaltungs-Operationen (add, remove) in Composite,
da sie für Leafs nicht anwendbar sind.
 Wunsch nach einheitlicher Behandlung aller Graphic-Objekte durch Clients
 Verwaltungs-Operationen in Component mit default-Implementierung
die nichts tut
 Leaf-Klassen sind damit zufrieden, Composites müssen die
Operationen passend implementieren.
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-132
ROOTS
Composite Pattern: Alternative Struktur
(add / remove nicht in „Component“)
*
Client
Component
children
operation()
getChildren()
Leaf
Composite
operation()
getChildren()
operation()
add(Component)
remove(Component)
getChildren()
operation() {
for all c in children
c.operation()
}
Component getChildren() {
return null
}
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-133
ROOTS
Composite Pattern: Konsequenzen
 Einheitliche Behandlung
 Teile
 Ganzes
 Einfache Clients
 Dynamisches Binden statt Fallunterscheidungen
 Leichte Erweiterbarkeit
 neue Leaf-Klassen
 neue Composite-Klassen
 ohne Client-Änderung
 Evtl. zu allgemein
 Einschränkung der Komponenten-Typen schwer
 „run-time type checks“ (instanceof)
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-134
ROOTS
Kapitel 6: Entwurfsmuster
Das Visitor Pattern
ROOTS
Das Visitor Pattern
 Absicht
 Repräsentation von Operationen auf Elementen einer Objektstruktur
 Neue Operationen definieren, ohne die Klassen dieser Objekte zu ändern
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-136
ROOTS
Visitor Pattern: Motivation
 Beispiel: Compiler
 enthält Klassenhierarchie für Ausdrücke einer Programmiersprache
 Problem
 Code einer Operation (z.B. Typüberprüfung) ist über mehrere Klassen
einer Datenstruktur verteilt
 Hinzufügen oder ändern einer Operation erfordert Änderung der gesamten
Hierarchie
Node
TypeCheck()
GenerateCode()
PrettyPrint()
VariableRefNode
TypeCheck()
GenerateCode()
PrettyPrint()
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
AssignmentNode
TypeCheck()
GenerateCode()
PrettyPrint()
Seite 7-137
ROOTS
Visitor Pattern: Idee (1)
 Visitor
 Klasse die alle visit...-Methoden zusammenfasst, die gemeinsam eine
Operation auf einer Objektstruktur realisieren
 Visit...-Methode
 Ausprägung der Operation auf einem bestimmtem Objekttyp
 Hat Parameter vom entsprechenden Objekttyp
 Kann somit alle Funktionalitäten des Typs nutzen um das zu besuchende
Objekt zu bearbeiten
Visitor
visitAssignment(AssignmentNode)
visitVariableRef(VariableRefNode)
TypeCheckingVisitor
CodeGeneratingVisitor
visitAssignment(AssignmentNode)
visitVariableRef(VariableRefNode)
visitAssignment(AssignmentNode)
visitVariableRef(VariableRefNode)
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-138
ROOTS
Visitor Pattern: Idee (2)
 Accept-Methoden in allen Klassen der betroffenen Klassenhierarchie
 Haben Visitor als Parameter
 „Diese Operation soll auf mir ausgeführt werden!“
 Rufen die jeweils zu ihnen passende visit...-Methode auf
 „Diese Variante der Operation muss auf mir ausgeführt werden!“
 Übergeben „this“ als Parameter
Program
*
Node
accept(NodeVisitor)
AssignmentNode
VariableRefNode
accept(NodeVisitor v)
accept(NodeVisitor v)
v.visitAssignment(this)
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
v.visitVariableRef(this)
Seite 7-139
ROOTS
Visitor Pattern: Schema (Statisch)
Client
Visitor
visitConcreteElementA(ConcreteElementA)
visitConcreteElementB(ConcreteElementB)
ConcreteVisitor1
ConcreteVisitor2
visitConcreteElementA(ConcreteElementA)
visitConcreteElementB(ConcreteElementB)
visitConcreteElementA(ConcreteElementA)
visitConcreteElementB(ConcreteElementB)
ObjectStructure
*
Element
accept(Visitor)
ConcreteElementA
accept(Visitor v)
operationA()
v.visitConcreteElementA(this)
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
ConcreteElementB
accept(Visitor v)
operationB()
v.visitConcreteElementB(this)
Seite 7-140
ROOTS
Visitor Pattern: Verantwortlichkeiten /
Implementation
 Objektstruktur-Hierarchie
 Einheitliche accept-Methode
 Visitor-Hierarchie
 Je eine visit-Methode für jede Klasse der Objektstruktur mit Parameter vom
Typ der jeweilige Klasse
 Traversierung der Objektstruktur kann definiert sein in
 der besuchten Objektstruktur (Methode accept(...)) oder
 dem Visitor-Objekt (Method visit...(...))
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-141
ROOTS
Visitor Pattern: Zusammenarbeit
welche Operation
:ObjectStructure
accept(v)
auf welchem Objekt
... ist wie implementiert
a:ConcreteElementA b:ConcreteElementB
v:ConcreteVisitor
accept(v)
visitConcreteElementA(a)
operationA()
accept(v)
visitConcreteElementB(b)
operationB()

© 2000-2010 Dr. G. Kniesel
Double dispatch
Vorlesung „Softwaretechnologie“ (SWT)

Seite 7-142
ROOTS
Das Visitor Pattern: Konsequenzen
 Hinzufügen neuer Operationen ist einfach.
 Neue Visitor-Klasse
 Hinzufügen neuer Objektklassen ist sehr aufwendig.
 Neue Objekt-Klasse
 Neue visit... - Methode in allen Visitors
 Sammeln von Zuständen
 Visitor-Objekte können Zustände der besuchten Objekte aufsammeln und (evtl.
später) auswerten.
 Eine Übergabe von zusätzlichen Parametern ist dafür nicht nötig.
 Verletzung von Kapselung
 Die Schnittstellen der Klassen der Objektstruktur müssen ausreichend
Funktionalität bieten, damit Visitor-Objekte ihre Aufgaben erledigen können.
 Oft muss mehr preisgegeben werden als (ohne Visitor) nötig wäre.
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-143
ROOTS
Das Visitor Pattern: Anwendbarkeit
 Funktionale Dekomposition
 Zusammengehörige Operationen sollen zusammengefasst werden
 ... statt in einer Klassenhierarchie verteilt zu sein
 Stabile Objekt-Hierarchie
 selten neue Klassen
 aber oft neue Operationen
 Heterogene Hierarchie
 viele Klassen mit unterschiedlichen Schnittstellen
 Operationen die von den Klassen abhängen
 Anwendungsbeispiel
 Java-Compiler des JDK 1.3
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-144
ROOTS
Das Visitor Pattern: Implementierung
 Abstrakter Visitor
 Jede Objektstruktur besitzt eine (abstrakte) Visitor-Klasse.
 Für jeden Typ T in der Objektstruktur, enthält die Visitor-Klasse je eine
Methode mit einem Parameter vom Typ T  visitT(T)
 Konkrete Visitors
 Jede Unterklasse der Visitor-Klasse redefinieren die visit-Methoden, um
ihre jeweilige Funktionalität zu realisieren.
 Jede konkrete visitT(T) Methode benutzt dabei die spezifischen
Operationen des besuchten Objekttyps T
 Traversierung der Objektstruktur
 kann in der Objektstruktur (accept(...) Methoden) definiert sein
 ... oder im Visitor-Objekt (visit...(...) Methoden).
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-145
ROOTS
Kapitel 6: Entwurfsmuster
Gemeinsamkeiten und Unterschiede
der Pattern
ROOTS
Abgrenzung: Facade, Singleton, Abstract
Factory
 Facade
 Versteckt Subsystem-Details (Typen und Objekte)
 Singleton
 Facaden sind meist Singletons (man braucht nur eine einzige)
 Abstract Factory
 Zur Erzeugung konsistenter Sätze von Subsystem-Objekten
 Als Alternative zu Facade  "Verstecken" plattform-spezifischer Klassen
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-147
ROOTS
Abgrenzung: Proxy, Decorator, Adpater
 Proxy
 gleiches Interface
 kontrolliert Zugriff
 "Implementierungs-Detail"
 Decorator
 erweitertes Interface
 zusätzliche Funktionen
 „konzeptionelle Eigenschaft“
 Adapter
 verschiedenes Interface
 ähnlich Protection-Proxy
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-148
ROOTS
Abgrenzung: Bridge, Adapter, Abstract
Factory
 Bridge
 antizipierte Entkopplung von Schnittstelle und Implementierung
 Adapter
 nachträgliche Anpassung der Schnittstelle einer Implementierung
 Abstract Factory
 nutzbar zur Erzeugung und Konfiguration einer Bridge
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-149
ROOTS
Abgrenzung: Factory / Template Method,
Abstract Factory, Prototype
 Factory Method
 Verzögerte Entscheidung über die Klasse eines zu erzeugenden Objektes
 Template Method
 ruft oft Factory Method auf
 Abstract Factory
 gleiche Motivation
 gruppiert viele Factory Methods die „zusammengehörige“ Objekte erzeugen
 erzeugt feste Menge von Objekten von festen Obejkttypen
 Prototype
 erfordert keine Unterklassenbildung
 ... dafür aber explizite initialize()-Methode
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-150
ROOTS
Kapitel 6: Entwurfsmuster
„Patterns Create Architectures“
Ein Beispiel zum Zusammenspiel von
Patterns
Bridge & Abstract Factory & Singleton
ROOTS
„Patterns Create Architectures“
 Idee
 Wenn man Patterns wohlüberlegt zusammen verwendet, entsteht ein
Grossteil einer Software-Architektur aus dem Zusammenspiel der Patterns.
 Beispiel
 Zusammenspiel von Bridge, Factory und Singleton
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-153
ROOTS
Erinnerung ans Abstract Factory Pattern
WidgetFactory
Client
createWindow()
createScrollBar()
in der Praxis müsste
WidgetFactory ein
Singleton sein
MotifWidgetFactory
createWindow()
createScrollBar()
PMWidgetFactory
Window
PMWindow
MotifWindow
createWindow()
createScrollBar()
Scrollbar
in der Praxis müsste
hier das BridgePattern angewendet
werden
PMScrollbar
MotifScrollBar
Erinnerung ans Bridge Pattern
 Trennung von
 Konzeptueller Hierarchie
 ImplementierungsHierarchie
Client
Window
imp
WindowImp
drawText()
drawRect()
devDrawText()
devDrawLine()
IconWindow
TransientWindow
PMWindowImp
XWindowImp
drawBorder()
drawCloseBox()
devDrawText()
devDrawLine()
devDrawLine()
devDrawText()
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-155
ROOTS
Zusammenspiel: Bridge, Factory,
Singleton WidgetFactory.setFactory(WidgetFactory.MOTIF)
<< konfiguriert >>
Client
<< fragt ab>>
WidgetFactory
setFactory(Type)
getFactory()
Singleton
WidgetFactory.getFactory()
PMWidgetFactory
MotifWidgetFactory
createWindow()
createScrollBar()
Window
IconWIndow
TransientWindow
Scrollbar
FixedSB
imp
imp
ProportionalSB
WindowImp
PMWindow
MotifWindow
ScrollbarImp
PMScrollbar
MotifScrollBar
Kapitel 6: Entwurfsmuster
Weitere Patterns
Kapitel „Systemenwurf“: Facade Pattern & Nutzung von Observer für Ebenen-Architekturen
Kapitel „Objektentwurf“: Alle „Split-Object“-Patterns (Strategy, State, Decorator, Overriding,
Multiple Vererbung)
ROOTS
Kapitel 6: Entwurfsmuster
Rückblick: Was nützen Patterns?
ROOTS
Nutzen von Design Patterns (1)
 Abstraktionen identifiziere, die kein Gegenstück in der realen Welt /
dem Analyse-Modell haben
 Beispiel:
 Command Pattern
 Composite Pattern
 Strategy
 State
 "Strict modelling of the real world leads to a system that reflects
today's realities but not necesarilly tomorrow's. The abstractions that
emerge during design are key to making a design flexible."
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-159
ROOTS
Nutzen von Design Patterns (2)
 Granularität der Objekte festlegen
 Visitor




 Gruppe von konsistenten Aktionen
Command
 einzelne Aktion
Facade
 ein "Riesen-Objekt"
Flyweight
 viele kleine, gemeinsam verwendbare Teilobjekte
Builder
 Komposition von Gesamt-Objekt aus Teilobjekten
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-160
ROOTS
Nutzen von Design Patterns (3)
 Schnittstellen identifizieren
 was gehört dazu
 was gehört nicht dazu (Bsp. Memento)
 Beziehungen zwischen Schnittstellen festlegen
 Subtyping
 Proxy
 Decorator
 Je eine Methode pro Klasse aus einer anderen Objekthierarchie
 Abstract Factory
 Visitor
 Builder
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-161
ROOTS
Nutzen von Design Patterns (4)
 Wahl der Implementierung
 Interface, Abstrakte Klasse oder konkrete Klasse?
 Grundthema fast aller Patterns
 Abstrakte Methode oder Hook Methode?
 von template method aufgerufene Methoden
 Overriding oder fixe Implementierung?
 Factory method
 Template method
 Vererbung oder Subtyp-Beziehung?
 Adapter, Decorator, State, Strategy, Command, Chain of Responsibility 
Gemeinsamer Obertyp, nicht gemeinsame Implementierung
 Vererbung oder Aggregation?
 Vererbung ist statisch, Aggregation dynamisch
 Wenn das „geerbte“ nicht in der Schnittstelle auftauchen soll: Aggregation und
Anfrageweiterleitung nutzen (anstatt Vererbun)
 Siehe alle "split object patterns"
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-162
ROOTS
Nutzen von Design Patterns (5):
Patterns verkörpern Grundprinzipien guten Designs
 Implementierungen austauschbar machen
 Typdeklarationen mit Interfaces statt mit Klassen
 Design an Interfaces orientieren, nicht an Klassen
 Client-Code wiederverwendbar für neue Implementierungen des gleichen
Interface
 Objekt-Erzeugung änderbar gestalten
 "Creational Patterns" statt "new MyClass()"
 Client-Code wiederverwendbar für neue Implementierungen des gleichen
Interface
 Funktionalität änderbar gestalten
 Aggregation und Forwarding statt Vererbung
 späte Konfigurierbarkeit, Dynamik
 weniger implizite Abhängigkeiten (kein "fragile base class problem")
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-163
ROOTS
Nichtfunktionale Anforderungen geben Hinweise
zur Nutzung von Entwurfsmustern
Identifikation von Entwurfsmustern anhand von Schlüsselwörtern in der
Beschreibung nichtfunktionaler Anforderungen
 Analog zu Abbot’s Technik bei der Objektidentifikation
 Facade Pattern
 „muss mit einer Menge existierender Objekte zusammenarbeiten”,
 „stellt Dienst bereit“
 Adapter Pattern
 „muss mit einem existierenden Objekt zusammenarbeiten”
 Bridge Pattern
 „muss sich um die Schnittstelle zu unterschiedlichen Systemen kümmern
von denen einige erst noch entwickelt werden.“
 „ein erster Prototyp muss vorgeführt werden“
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-164
ROOTS
Nichtfunktionale Anforderungen geben Hinweise
zur Nutzung von Entwurfsmustern (Fortsetzung)
 Proxy Pattern
 “muss ortstransparent sein”
 Observer Pattern
 “muss erweiterbar sein”, “muss skalierbar sein”
 Strategy Pattern
 “muss Funktionalität X in unterschiedlichen, dynamisch auswählbaren
Ausprägungen bereitstellen können”
 Composite Pattern
 „rekursive Struktur“, “komplexe Struktur”
 “muss variable Tiefe und Breite haben”
 Abstract Factory Pattern
 “Herstellerunabhängig”,
 “Geräteunabhängig”,
 “muss eine Produktfamilie unterstützen”
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-165
ROOTS
Überblick
 Einführung
 Grundidee, Literatur, MVC-Framework als Beispiel
 Beispiele wichtiger Patterns
 Observer, Strategy, Command
 Facade, Singleton, Proxy, Adapter, Bridge
 Factory Method, Abstract Factory
 Composite, Visitor
 Patterns Create Architectures
 Bridge, Abstract Factory, Singleton
 Nutzen von Patterns
 Zusammenfassung und Ausblick
 Arten von Patterns, Abgrenzung
 Weiterführende Themen
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-166
ROOTS
Arten von Pattern
 Analysis Pattern
 Wiederkehrende Problemen in der Analysephase eines Softwareprojekts
 Martin Fowler: "Analysis Patterns", Addison-Wesley, 1997
 Architecture Pattern
 ... beschreibt mögliche fundamentale Strukturen von Softwaresystemen.
 ... enthält vordefinierte Subsysteme und ihre Verantwortlichkeiten.
 ... enthält Regeln und Richtlinien für die Organisation ihrer Beziehungen.
 Beispiel: Model-View-Controller
 Design Pattern
 Schema für die Realisation von Subsystemen oder Komponenten eines
Softwaresystems
 Idiom (auch: Coding Pattern)
 Low-level design patterns für eine gegebene Programmiersprache.
 Beispiel: Wie stelle ich sicher, dass eine Instanz einer Java-Klasse nur
innerhalb einer bestimmten anderen Klasse erzeugt werden kann?
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-167
ROOTS
Weitere Arten von Pattern
 Organizational Patterns
 Struktur und Praxis von Organisationen; also Gruppen, die ein
gemeinsames Ziel verfolgen
 http://en.wikipedia.org/wiki/Organizational_patterns
 Anti-Patterns
 beschreiben typische Fehler
 ... und bestenfalls auch wie man sie wieder beseitigt
 http://de.wikipedia.org/wiki/Anti-Pattern
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-168
ROOTS
AbgrenzungPattern versus Algorithmen
 Abstraktheit
 Algorithmen lösen konkrete Probleme im Anwendungsbereicht (z.B.
Suchen, Sortieren)
 Pattern lösen generische Entwurfsprobleme (Dynamik, Wartbarkeit, ...)
 Unvollständigkeit / Schablonenhaftigkeit
 Algorithmen sind vollständig  Komplexität genau ermittelbar
 Pattern sind „nur“ Schablonen für gewisse Schlüsselinteraktionen, Rest ist
beliebig
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-169
ROOTS
AbgrenzungPattern versus Frameworks
 Framework
 Menge von kooperierenden Klassen für einen spezifischen
Anwendungsbereich
 Erweiterbar durch Unterklassenbildung und Komposition von Instanzen
 Hollywood-Prinzip ("Don't call us, we'll call you." --> Template Method
Pattern)
 Pattern versus Frameworks
 Patterns sind abstrakter
 Frameworks existieren als konkreter, wiederverwendbarer Code
 Patterns sind nur Schablonen für Code
 Patterns sind nicht anwendungsabhängig
 Frameworks werden für konkrete Anwendungsbereiche eingesetzt
 Patterns sind anwendungsunabhängig
 Frameworks nutzen Patterns
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-170
ROOTS
Weiterführende Themen
 Pattern Catalogs
 Sammlungen von lose zusammenhängenden Patterns
 http://hillside.net/patterns/patterns-catalog
 Pattern Systems
 Sammlungen von stark zusammenhängenden Patterns mit engen
Verzahnungen
 Pattern Languages
 verfolgen ein gemeinsames Ziel, dass durch die Zusammenarbeit der
enthaltenen Patterns erreicht werden kann
 inkl. einer Art "Grammatik", die alle mögliche Kombinationen aufzeigt
 http://en.wikipedia.org/wiki/Pattern_language
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-171
ROOTS
Pattern  Zusammenfassung
 Betonung von Praktikabilität
 Patterns sind bekannte Lösungen für erwiesenermaßen wiederkehrende
Probleme
 Lösungen, die sich noch nicht in der Praxis bewährt haben, sind keine
Pattern.
 Patterns sind kein Allheilmittel
 Originalität bei der Anwendung von Patterns ist nach wie vor gefragt.
 Es muss immer noch abgewägt werden, welche Patterns eingesetzt
werden.
 Gesamteffekt
 Aufgabe des Softwarearchitekten verlagert sich von der Erfindung des
Rades zur Auswahl des richtigen Rades und seiner kreativen Anwendung
© 2000-2010 Dr. G. Kniesel
Vorlesung „Softwaretechnologie“ (SWT)
Seite 7-172
ROOTS
Herunterladen