Sie sind auf Seite 1von 147

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% Model
b = 30%
c = 20%
2. Änderungen
am Modell
werden
propagiert

- X - X

a = 50%
b = 30%
1. Views melden sich an c = 20%

View + Controller View + Controller

© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) Seite 7-4 ROOTS


Einführung: Das MVC-Framework in
Smalltalk als Beispiel

a = 50% Model
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%

 Propagierung von Änderungen: Observer Pattern b = 30%


c = 20%

 Kommt z.B. auch bei Client/Server-Programmierung


zur Benachrichtigung der Clients zum Einsatz X
-

 Geschachtelte Views: Composite Pattern


- X

 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).

 Reaktion auf Events im Controller: Strategy Pattern


 Eingabedaten können validiert werden X
(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 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%

- - - a = 50%

 Abhängigkeiten 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)
<<interface>> * 1 {abstract}
Observer observers subject Subject

observers.add(o)
update() :void attach(o:Observer):void
observers.remove(o) detach(o:Observer):void
notify() : void
for all o in observers {
o.update();
}

ConcreteObserver ConcreteSubject
{redefines subject} subjectState:State
1
update() :void return subjectState; getState() : State
… setState(State s): void
subject.getState(); subjectState = s;
… notify()
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>> * 1 {abstract}
Observer observers subject Subject

observers.add(o)
update(StateA) :void attach(o:Observer):void
observers.remove(o) detach(o:Observer):void
notify() : void

ConcreteObserver ConcreteSubject
subjectStateA:StateA
subjectStateB:StateB
update(StateA) :void notify() : void
for all o in observers { setState(State s): void
o.update(subjectStateA);
}
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 :Model


GraphView1
Model setState(…)
GraphView…
GraphViewJ update()
setState(…) pie=toPieChart()
update()
setGraph(BarChart p)
toPieChart() setGraph(pie)
draw()
toBarChart()
draw()
toString()
TextView1
TextView… s = toString()
print() TextViewN
print(s)
print()
print()
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>> * 1
Subject :View :Model
Observer observers subject

attach(this)
update() :void attach(o:Observer)
detach(o:Observer)
notify()
setState()
for all o in observers {
o.update(); notify()
}

update()

View Model getState()


{redefines subject}
subjectState:State
1
update() :void getState() : State
setState(State s)
subject.getState();

Nettoeffekt: Abhängigkeits- und
Kontrollumkehrung
Abhängigkeitsumkehrung Kontrollumkehrung
(„Dependency Inversion“) („Inversion of Control“)
 Ohne Observer  Ohne Observer
 Abhängigkeit Model  Views  Model steuert alle updates
 Mit Observer  Mit Observer
 Abhängigkeit Model  Views  Jeder View steuert sein
update
Vergleich Ablauf ohne / mit Observer

:TextViewN … :GraphView1 :Model :View :Model

setState(…) attach(this)

update() setState()
pie=toPieChart() notify()
setGraph(pie)
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
 Template Method
Bisher
 Chain of Responsibility
 Decorator
 State  Proxy Jetzt
 Strategy  Adapter
 Multiple Vererbung  Bridge
 Facade

Split Objects

 Factory Method  Prototype


 Abstract Factory  Singleton
 Builder Objekt-Erzeugung
Klassifikation: „Was“ und „Wie“

 Verhaltens-Patterns
 Verhalten leicht erweiterbar, komponierbar, dynamisch änderbar oder
explizit manipulierbar machen
 Struktur-Patterns
Was?

 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.
 Split Object Patterns
 Ziel: Dynamisch änderbares Verhalten, gemeinsame Verwendung oder
Wie?

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:

private Singleton() {
this.Singleton(arg1, ..., argN);
Singleton }
private Singleton(...) { Liefert eine Instanz (typischerweise immer die
getInstance() Selbe):
...
instanceOperation() }
public static Singleton getInstance() {
-instancePool
if (instancePool == null)
-instanceData Speichert die einzige instancePool = new Singleton();
Instanz oder begrenzte return instancePool;
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
image file
:TextDocument :ImageProxy :Image

Hauptspeicher Platte

© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) Seite 7-52 ROOTS


Proxy Pattern: Beispiel

<<interface>> *
DocumentEditor
Graphic
draw()
getExtent()
store()
load()

if (image == 0){
<<creates>> image = loadImage(filename);
Image ImageProxy }
imageData fileName image.draw()
extent extent
draw() draw()
image if (image == 0){
getExtent() getExtent()
store() store() return extent;
load() load() } else {
return image.getExtent();
}

© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) Seite 7-53 ROOTS


Proxy Pattern: Schema

<<interface>> *
Client
Subject

request()
...

realSubject
RealSubject Proxy
...
request() request() realSubject.request();
... ... ...

:RealSubject :Proxy :Client


 request()  request()

© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) 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(...)
: Guard

requestor : Object getObject()


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 TextView-
Methoden

© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) Seite 7-65 ROOTS


Adapter Pattern: Beispiel

Existierende Klassen
*
DrawingEditor Shape
Adapter-Klasse
BoundingBox()
CreateManipulator()

text
Line TextShape TextView

BoundingBox() BoundingBox() getExtent()


CreateManipulator() CreateManipulator() ...

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()

Adapter
… Adaptee_N …
request()
f()
adaptee.other()

:Client :Adapter :Adaptee_N

request()
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()

Adapter
… Adaptee_N …
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 Adaptee
adaptee
request() other() f()
f()

Adapter
… Adaptee_N …
request()
f()

…‘ Adaptee_N‘ …‘
f() f() 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()

<<implementation inheritance>>

Adapter
… Adaptee_N …
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()

<<implementation inheritance>>

Adapter
… Adaptee_N …
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
 adaptiert nur eine Klasse Client Target Adaptee
request() f()
 ... nicht ihre Unterklassen m()

 Overriding des Adaptee-Verhaltens leicht möglich Adapter


Adapt_N
request()
 keine zusätzliche Indirektion (nur ein Objekt) f()
m()

 Object Adapter :Client :Adapter :Adaptee

 adaptiert eine ganze Klassenhierarchie


 Overriding schwieriger
 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:
– X-Windows,
– IBM Presentation Manager,
– MacOS,
– Windows XYZ,
– ...

© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) Seite 7-84 ROOTS


Bridge Pattern: Warum nicht einfach Vererbung
einsetzen?

Neue Fenster-Art:
"iconifizierbare" Fenster
Window Window

XWindow PMWindow XWindow PMWindow IconWindow

 Probleme dieses Lösungsversuchs 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() devDrawText()
drawRect() devDrawLine()

imp.devDrawLine()
imp.devDrawLine()
imp.devDrawLine()
imp.devDrawLine()

IconWindow TransientWindow XWindowImp PMWindowImp


drawBorder() drawCloseBox() devDrawText() devDrawLine()
devDrawLine() devDrawText()

drawRect()
drawText() drawRect() XDrawLine() XDrawString()
Bridge Pattern: Schema

Client

imp
Abstraction Implementor
operation() basicOperation()

imp.basicOperation()

RefinedAbstraction ConcreteImplementorA ConcreteImplementorB


basicOperation() basicOperation()

© 2000-2010 Dr. G. Kniesel 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 Struktur
 Visitor  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 * Application
docs Document doc = doCreateDocument();
newDocument()
doCreateDocument() docs.add(doc);
doc.open();

MyDocument MyApplication
doCreateDocument() return new MyDocument()

Applikation
Factory Method: Schema

Product Creator ...


anOperation() product = factoryMethod();
factoryMethod() ...

ConcreteProduct 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 LineManipulator Textmanipulator


createManipulator() createManipulator() downClick() downClick()
... ... drag() drag()
upClick() 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" class Creator {


 jede Unterklasse erzeugt Product create(){ MyProduct(); }
}
festgelegte Produkt-Art

 Codierter "Produkt-Typ"
 Parameter oder Objekt-Variable class Creator {
kodiert "Produkt-Typ" Product create(int id) {
if (id==1) return MyProduct1();
 Fallunterscheidung anhand if (id==2) return MyProduct2();
Code ...
 mehrere Produkte }
}
 mehr Flexibilität Idiom reflektiver Sprachen
• Smalltalk
 Klassen-Objekt als "Produkt-Typ" • Java

 Parameter oder Objekt-Variable class Creator {


ist "Produkt-Typ" Object create(Class prodType) {
return prodType.getInstance();
 direkte Instantiierung }
 mehr Flexibilität } Reflektiver Aufruf des parameterelosen
 bessere Wartbarkeit Default-Konstruktors
 kein statischer Typ-Check
© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) 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 PMWidgetFactory PMWindow MotifWindow


createWindow() createWindow()
createScrollBar() createScrollBar()

Scrollbar

PMScrollbar MotifScrollBar

© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) Seite 7-104 ROOTS


Abstract Factory: Schema

AbstractFactory Client
createProductA()
createProductB()

AbstractProductA

ConreteFactory1 ConreteFactory2 ProductA2 ProductA1


createProductA() createProductA()
createProductB() createProductB()

AbstractProductB

ProductB2 ProductB1

© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) 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 Struktur
 Visitor  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()
document
cut() PasteCommand
copy()
execute() Verschiedene
paste()
Implementierungen

document.paste();
Command Pattern: Schema und Rollen

<<interface>>
Client Invoker
Command
setCommand() execute()

Receiver ConcreteCommand
action() execute()

 Command Interface  Execute-Methode


 Schnittstelle, die festlegt, was  Ausführen von Kommandos
Commands tun können  Undo-Methode
 Mindestens Execute, optional auch
 Rückgängig machen von
Undo, Redo
Kommandos
 Concrete Command
 Redo-Methode
 Implementiert Command Interface
 Rückgängig gemachtes Kommando
 „Controllers“ sind oft wieder ausführen
„ConcreteCommands“
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 Command-
Objekte 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>>

:MenuItem MyPasteCommand
void actionPerfomed(ActionEvent evt)

:Button
 addActionListener(ActionListener)
: MyPasteCommand
 actionPerformed(ActionEvent)
:JComponent
 registerKeyboardAction(ActionListener, KeyStroke, ...)

 Observer  Command & Observer


 Buttons, Menue-Einträge und Tasten  gleiche Methode (z.B. actionPerformed)
generieren "ActionEvents" spielt die Rolle der run() Methode eines
 Interface "ActionListener" ist vordefiniert Commands und die Rolle der update()
Methode eines Observers
 "ActionListener" implementieren  implementierende Klasse (z.B.
 ... und Instanzen davon bei Buttons, MyPasteCommand) ist gleichzeitig ein
MenuItems, etc registrieren Command und ein Observer
Verbindung von Observer und Command
in Java verbindet auch Push und Pull
<<interface>>
ActionListener
void actionPerfomed(ActionEvent evt)

<<implements>>

:MenuItem MyPasteCommand
void actionPerfomed(ActionEvent evt)

:Button
 addActionListener(ActionListener)
: MyPasteCommand
 actionPerformed(ActionEvent)
:JComponent
 registerKeyboardAction(ActionListener, KeyStroke, ...)

 Push Observer  Pull Observer


 Subject „pushed“ eine „Event“-Instanz  Die als Parameter übergebene
 Der „Event“-Typ kann selbst definiert „Event“-Instanz enthält immer eine
werden Referenz auf die Quelle des Events
 Somit ist es möglich von dort weitere
 In dieser Instanz können somit weitere Informationen zu anzufragen („pull“)
Informationen mit „gepushed“ werden
(als Werte von Instanzvariablen)
Verbindung von Observer und Command
in Java (2)
 Zusätzliche Unterstützung für <<interface>>
"Command" ActionListener
 Interface "Action" und Klasse void actionPerfomed(ActionEvent evt)
"AbstractAction"
<<extends>>
Aktivierung /
<<interface>>
Deaktivierung

im JDK enthalten
Action
von
MenuItems void putValue(String key, Object value)
denen diese Object getValue(String key) Einheitliche Schnittstelle zur
"Action" Speicherung von Parametern
zugeordnet boolean isEnabled() für "Action" ...
ist void setEnabled(boolean b)
void addPropertyChangeListener(PropertyChangeListener listener)
void removePropertyChangeListener(PropertyChangeListener listener)
... Parameter
können <<implements>>
allerdings
AbstractAction
auch direkt als
Instanz- // alles ausser void actionPerfomed(ActionEvent evt)
Variablen
realisiert <<extends>>
werden.
MyPasteCommand
void actionPerfomed(ActionEvent evt)
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();
}
class ActionButton extends JButton
private Component target;
{ public ActionButton(Action a)
private Color color;
{ ...
}
addActionListener(a);
}
 ColorAction }

 Ä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
children
draw()
add(Graphic)
remove(Graphic)
getChildren()

Line Text Picture draw() {


draw() draw() draw() for all c in children
add(Graphic) c.draw()
remove(Graphic) }
getChildren()

:Line :Text

:Text :Picture :Picture

© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) Seite 7-129 ROOTS


Composite Pattern: Struktur

*
Client Component
children
operation()
add(Component)
remove(Component)
getChildren()

Leaf Composite operation() {


operation() operation() for all c in children
add(Component) add(Component) c.operation()
remove(Component) remove(Component) }
getChildren() getChildren()

add() {}
oder
add() {throw new MessageNotSupportedException()}

© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) Seite 7-130 ROOTS


Composite Pattern: Verantwortlichkeiten
*
Component
 Component (Graphic) children
operation()
 gemeinsames Interface aller Teilobjekte add(Component)
 default-Verhalten remove(Component)
getChildren()
 Interface für Zugriff auf Teilobjekte (!)
 evtl. Interface für Zugriff auf Elternobjekte

 Leaf (Rectangle, Line, Text) Leaf Composite


 "primitive" Teil-Objekte operation() operation()
add(Component)
 implementieren gemeinsames Interface remove(Component)
 leere Implementierungen für Teilzugriffs-Interface getChildren()

 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


*
children
operation()
 Explizite Referenzen auf Composite in add(Component)
remove(Component)
Component Klasse getChildren()

 Wenn mehrere Composites Components

parent
gemeinsam nutzen sollen

1
Leaf Composite
 Schließt explizite Referenz der Components operation() operation()
add(Component)
auf Composite aus oder erfordert, dass Components remove(Component)
getChildren()
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() {


operation() operation() for all c in children
getChildren() add(Component) c.operation()
remove(Component) }
getChildren()

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 AssignmentNode
TypeCheck() TypeCheck()
GenerateCode() GenerateCode()
PrettyPrint() PrettyPrint()

© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) 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) visitAssignment(AssignmentNode)
visitVariableRef(VariableRefNode) 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) v.visitVariableRef(this)

© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) Seite 7-139 ROOTS


Visitor Pattern: Schema (Statisch)
Client Visitor
visitConcreteElementA(ConcreteElementA)
visitConcreteElementB(ConcreteElementB)

ConcreteVisitor1 ConcreteVisitor2
visitConcreteElementA(ConcreteElementA) visitConcreteElementA(ConcreteElementA)
visitConcreteElementB(ConcreteElementB) visitConcreteElementB(ConcreteElementB)

ObjectStructure * Element
accept(Visitor)

ConcreteElementA ConcreteElementB
accept(Visitor v) accept(Visitor v)
operationA() operationB()

v.visitConcreteElementA(this) v.visitConcreteElementB(this)

© 2000-2010 Dr. G. Kniesel Vorlesung „Softwaretechnologie“ (SWT) 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 auf welchem Objekt ... ist wie implementiert

:ObjectStructure a:ConcreteElementA b:ConcreteElementB v:ConcreteVisitor


accept(v)
accept(v)
visitConcreteElementA(a)

operationA()

accept(v)
visitConcreteElementB(b)

operationB()

 Double dispatch 

© 2000-2010 Dr. G. Kniesel 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 Window
Singleton sein

MotifWidgetFactory PMWidgetFactory PMWindow MotifWindow


createWindow() createWindow()
createScrollBar() createScrollBar()

Scrollbar

in der Praxis müsste


hier das Bridge-
Pattern angewendet
PMScrollbar MotifScrollBar
werden
Erinnerung ans Bridge Pattern

 Trennung von  Implementierungs-


Hierarchie
 Konzeptueller Hierarchie

Client
imp
Window WindowImp
drawText() devDrawText()
drawRect() 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 WidgetFactory
setFactory(Type) Singleton
getFactory()
<< fragt ab>>

WidgetFactory.getFactory()
PMWidgetFactory MotifWidgetFactory
createWindow()
createScrollBar()

Window imp
WindowImp

IconWIndow TransientWindow PMWindow MotifWindow

Scrollbar imp ScrollbarImp

FixedSB ProportionalSB 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