Folien - Fakultät Informatik Uni Stuttgart

Werbung
© Markus Knauß, 2008
Entwurfsmuster
Entwurfsmuster
Markus Knauß
[email protected]
1
© Markus Knauß, 2008
Motivation
Entwurfsmuster helfen nicht nur bei der Erstellung eines Entwurfs,
sie sind auch nützlich, um ein bestehendes Programm neu zu
strukturieren.
Entwurfsmuster
In den kommenden zwei Vorlesungsterminen wird ein
bestehendes Programm mit Entwurfsmustern neu strukturiert.
2

Praktische Anwendung eines Entwurfsmusters

Erkennen der Vorteile und Nachteile von Entwurfsmustern

Überblick über objektorientierte Konzepte und Entwurfsmuster
Entwurfsmuster
© Markus Knauß, 2008
Ziele
3
Nutzung einer Datenbank für die Speicherung der Eintragungen
eines Geburtstagskalenders.
Entwurfsmuster
© Markus Knauß, 2008
Geburtstagskalender
4
© Markus Knauß, 2008
Entwurfsmuster
Inhalt

Java Database Connectivity (JDBC)

Objektorientierte Konzepte

Template Method Pattern

Entwurfsmuster

Geburtstagskalender mit Entwurfsmustern

Zusammenfassung

Literatur und Links
5
© Markus Knauß, 2008
Java Database Connectivity (JDBC)
JDBC bietet eine plattformunabhängige Schnittstelle für die
Nutzung von Datenbanken in Java-Programmen.
Entwurfsmuster
Das JDBC-API definiert Interfaces, welche die zentralen
Datenbankfunktionen kapseln.

Verbinden mit einer Datenbank

Eine Anweisung ausführen

Ergebnisse einer Anweisung auswerten
6
© Markus Knauß, 2008
JDBC Übersicht
ResultSet
erzeugt
Statement
erzeugt
PreparedStatement
erzeugt
CallableStatement
Entwurfsmuster
erzeugt
Connection
erzeugt
DriverManager
implementiert
herstellerspezifischer
Datenbanktreiber
greift zu auf
java.sql.*
implementiert
JDBC-ODBC Brücke
Datenbank
ODBC Treiber
greift zu auf
7
© Markus Knauß, 2008
Entwurfsmuster
java.sql.Driver
Ein Datenbankanbieter, der eine JDBC-Implementierung anbieten
möchte, muss eine eigene Implementierung für das Interface
java.sql.Driver liefern.
Der JDBC DriverManager (java.sql.DriverManager)
verwaltet in einer JVM verfügbare Datenbanktreiber
(java.sql.Driver) und bietet Zugriff auf die Funktionen der
verfügbaren Treiber.
Um einen Treiber in der JVM verfügbar zu machen, muss dessen
implementierende Klasse mit dem Klassenlader geladen werden.
Hinweis: Der DriverManager ist ein Broker, der Zugriff auf die
Driver-Implementierungen erlaubt. Driver-Implementierungen sind
Factories für den Zugriff auf eine Datenbank.
8
© Markus Knauß, 2008
JDBC am Beispiel
// Datenbanktreiber laden
Class.forName(
"org.apache.derby.jdbc.EmbeddedDriver");
// Verbindung zur Datenbank herstellen
Connection con = DriverManager.getConnection(
"jdbc:derby:/Users/knaussms/tmp/address");
// Auszuführende Anweisung erstellen
Entwurfsmuster
Statement stmt = con.createStatement();
// Anweisung ausführen
ResultSet rs = stmt.executeQuery(
"SELECT * FROM persons");
// Ergebnisse auswerten
while (rs.next()) {
int id
= rs.getInt("id");
String firstName = rs.getString("first_name");
String lastName = rs.getString("last_name");
Date dateOfBirth = rs.getDate("date_of_birth");
DateFormat dateFormat =
DateFormat.getDateInstance(DateFormat.MEDIUM);
System.out.println(Integer.toString(id) +
": " + firstName + " " +
lastName + ", " +
dateFormat.format(dateOfBirth));
}
Die einzige herstellerspezifische
Anweisung ist das Laden des
Datenbanktreibers.
Konfigurationsspezifische
Anweisungen sind das
Verbinden mit der Datenbank
und der Zugriff auf Tabellen und
Spalten.
Alle weiteren Befehle sind
unabhängig von der
verwendeten Datenbank.
// Verbindung zur Datenbank schließen
con.close();
SimpleJDBC.java
9
© Markus Knauß, 2008
Einschub: PersonDB
<<interface>>
IPerson
+setFirstName(firstName:String)
+getFirstName():String
+setLastName(lastName:String)
+getLastName():String
+setDateOfBirth(dateOfBirth:Calendar)
+getDateOfBirth():Calendar
<<interface>>
IDBObject
+getId():int
Entwurfsmuster
PersonBean
Die Klasse PersonDB
implementiert alle Funktionen
für die Speicherung, das Laden,
das Ändern und das Löschen
von GeburtstagskalenderEinträgen in einer Datenbank.
-firstName:String
-lastName:String
-dateOfBirth:Calendar
PersonDB
-id:int
+create(person:IPerson):PersonDB
+read(id:int):PersonDB
+select(qbe:IPerson):List<PersonDB>
+read()
+update()
+delete()
implementiert
erbt von
10
© Markus Knauß, 2008
Entwurfsmuster
Aufgabe
Markieren Sie die einzelnen Schritte für den Datenbankzugriff in
den Methoden create, read, update, delete und select der
Klasse PersonDB.

Welche Anweisungssequenzen können Sie identifizieren?

Welche Teile der Sequenzen sind gleich, wo unterscheiden sie
sich?
con = DriverManager.getConnection(DB_URL);
Mit Datenbank verbinden
PreparedStatement ps = con.prepareStatement(DELETE_STMT);
Statement erstellen
ps.setInt(1, getId());
ps.execute();
Statement intialisieren
und ausführen
con.close();
Verbindung schließen
PersonDB.java
11
© Markus Knauß, 2008
Entwurfsmuster
Beispiel einer Lösung:
Gleichbleibende Anweisungssequenzen
public void read() {
Connection con
= null;
try {
con = DriverManager.getConnection(DB_URL);
PreparedStatement ps = con.prepareStatement(READ_STMT);
ps.setInt(1, getId());
ResultSet rs = ps.executeQuery();
while (rs.next()) {
setFirstName(rs.getString("fist_name"));
setLastName(rs.getString("last_name"));
setDateOfBirth(toCalendar(rs.getDate("date_of_birth")));
}
} catch (SQLException e) {
log.log(Level.SEVERE, e.getMessage(), e);
}
finally {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
log.log(Level.SEVERE, e.getMessage(), e);
}
}
}
}
Verbindung herstellen
Statement erstellen und initialisieren
Statement ausführen
Resultate auswerten
Verbindung schließen
12
© Markus Knauß, 2008
Entwurfsmuster
Beispiel einer Lösung:
Unterschiede
public void read() {
Connection con
= null;
try {
con = DriverManager.getConnection(DB_URL);
PreparedStatement ps = con.prepareStatement(READ_STMT);
ps.setInt(1, getId());
ResultSet rs = ps.executeQuery();
while (rs.next()) {
setFirstName(rs.getString("fist_name"));
setLastName(rs.getString("last_name"));
setDateOfBirth(toCalendar(rs.getDate("date_of_birth")));
}
} catch (SQLException e) {
log.log(Level.SEVERE, e.getMessage(), e);
}
finally {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
log.log(Level.SEVERE, e.getMessage(), e);
}
}
}
}
Statements
Initialisierung
Auswertung
13
© Markus Knauß, 2008
Entwurfsmuster
Inhalt

Java Database Connectivity (JDBC)

Objektorientierte Konzepte

Template Method Pattern

Entwurfsmuster

Geburtstagskalender mit Entwurfsmustern

Zusammenfassung

Literatur und Links
14
© Markus Knauß, 2008
Klassen
ModelFactory
-instance:ModelFactory
+getInstance():ModelFactory
Eine Klasse ist eine Schablone
für Objekte, die aus der Klasse
erzeugt werden können.
Entwurfsmuster
Jede Klasse existiert nur einmal
in einem laufenden Programm.
Eine Klasse kann einen Zustand
haben und Methoden anbieten.
15
© Markus Knauß, 2008
Entwurfsmuster
Objekte
Person
-firstName:String
-lastName:String
-dateOfBirth:Calendar
+getFirstName():String
+setFirstName(firstName:String)
+getLastName():String
+setLastName(lastName:String)
+getDateOfBirth():Calendar
+setDateOfBirth(dateOfBirth:Calendar)
JaggerMick:Person
RichardsKeith:Person
-firstName=“Mick“
-lastName=“Jagger“
-dateOfBirth='26.7.1943'
-firstName=“Keith“
-lastName=“Richards“
-dateOfBirth='18.12.1943'
Objekte werden aus Klassen
erzeugt (instantiiert).
Aus jeder Klassen können
beliebig viele Objekte erzeugt
werden.
Jedes Objekt hat eine Identität
und einen Zustand.
16
© Markus Knauß, 2008
Entwurfsmuster
Vererbung
Vererbung drückt eine „ist ein“Beziehung aus.
Person
-firstName:String
-lastName:String
-dateOfBirth:Calendar
+getFirstName():String
+setFirstName(firstName:String)
+getLastName():String
+setLastName(lastName:String)
+getDateOfBirth():Calendar
+setDateOfBirth(dateOfBirth:Calendar)
Objekte von erbenden Klassen
können an Stelle von Objekten
der vererbenden Klasse
verwendet werden.
List<Person> persons = new ArrayList<Person>();
-id:int
public void store(Person person) {
persons.add(person);
}
+create(person:IPerson):PersonDB
+read(id:int):PersonDB
+select(qbe:IPerson):List<PersonDB>
+read()
+update()
+delete()
public static void main(String[] args) {
PersonBean personBean = new PersonBean();
PersonDB personDB = new PersonDB();
store(personBean);
store(personDB);
}
PersonBean
PersonDB
17
© Markus Knauß, 2008
Polymorphie
Erbende Klassen können Methoden überschreiben.
Durch das Überschreiben kann das Verhalten einer Methode
verändert werden.
Entwurfsmuster
Polymorphie = Vielgestaltigkeit, Verschiedengestaltigkeit
18
© Markus Knauß, 2008
Polymorphie
Person
-firstName:String
Entwurfsmuster
+getFirstName():String
+setFirstName(firstName:String)
public String getFirstName() {
read();
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
update();
}
PersonBean
PersonDB
+getFirstName():String
+setFirstName(firstName:String)
+getFirstName():String
+setFirstName(firstName:String)
+read()
+update()
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
19
© Markus Knauß, 2008
Abstrakte Klassen, abstrakte Methoden
Person
DBObject
Entwurfsmuster
+getFirstName():String
+setFirstName(firstName:String)
+getLastName():String
+setLastName(lastName:String)
+getDateOfBirth():Calendar
+setDateOfBirth(dateOfBirth:Calendar)
PersonBean
-firstName:String
-lastName:String
-dateOfBirth:Calendar
+getId():int
+read()
+update()
+delete()
PersonDB
-id:int
+create(person:IPerson):PersonDB
+read(id:int):PersonDB
+select(qbe:IPerson):List<PersonDB>
Von abstrakten Klassen können
keine Objekte erzeugt werden.
Abstrakte Methoden haben
keine Implementierung, sie
müssen in der erbenden Klasse
überschrieben werden.
Abstrakte Methoden können nur
in abstrakten Klassen deklariert
werden.
20
© Markus Knauß, 2008
Entwurfsmuster
Aufgabe

Kapseln Sie die spezifischen Anweisungsteile der readMethode in eigenen Methoden.

Skizzieren Sie die Klasse DBStatement, in der die Methoden,
in denen die spezifischen Anweisungsteile der read-Methode
zusammengefasst sind, mit einer Standardimplementierung
realisiert sind.

Skizzieren Sie die von DBStatement erbende Klasse
ReadStatement, in der die Methoden mit den spezifischen
Anweisungsteilen der read-Methode enthalten sind.

Überarbeiten Sie die Implementierung der read-Methode so,
dass nur die Methoden mit den spezifischen Anweisungsteilen
aus der Klasse ReadStatement verwendet werden.
21
© Markus Knauß, 2008
Beispiel einer Lösung:
Klasse DBStatement
public abstract class DBStatement {
public abstract String getStatement();
public void initParameter(PreparedStatement stmt)
throws SQLException {
}
Entwurfsmuster
public void evaluateResults(ResultSet rs)
throws SQLException {
}
}
DBStatement.java
22
© Markus Knauß, 2008
Beispiel einer Lösung:
Klasse ReadStatement
public class ReadStatement extends DBStatement {
private
private
private
private
int id;
String firstName;
String lastName;
Calendar dateOfBirth;
Entwurfsmuster
@Override
public String getStatement() {
return "SELECT * FROM persons WHERE id = ?";
}
@Override
public void initParameter(PreparedStatement stmt) throws SQLException {
stmt.setInt(1, id);
}
@Override
public void evaluateResults(ResultSet rs) throws SQLException {
firstName = rs.getString("fist_name");
lastName = rs.getString("last_name");
dateOfBirth = CalendarUtils.toCalendar(rs.getDate("date_of_birth"));
}
// Get and set methods for attributes.
}
ReadStatement.java
23
© Markus Knauß, 2008
Entwurfsmuster
Beispiel einer Lösung:
read()-Methode
private ReadStatement readStatement = new ReadStatement();
public void read() {
Connection con = null;
try {
con = DriverManager.getConnection(DB_URL);
PreparedStatement ps = con.prepareStatement(readStatement.getStatement());
readStatement.setId(getId());
readStatement.initParameter(ps);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
readStatement.evaluateResults(rs);
}
} catch (SQLException e) {
log.log(Level.SEVERE, e.getMessage(), e);
}
finally {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
log.log(Level.SEVERE, e.getMessage(), e);
}
}
}
}
PersonDB.java
24
© Markus Knauß, 2008
Was wurde erreicht?
Die Implementierung der speziellen Teile einer DatenbankAnweisung können in eigenen Klassen gekapselt werden.
Entwurfsmuster
Der Algorithmus für die Ausführung einer Anweisung ist in allen
Methoden gleich!
DBStatement
+getStatement():String
+initParameter(stmt:PreparedStatement)
+evaluateResults(rs:ResultSet)
CreateStatement
ReadStatement
UpdateStatement
DeleteStatement
25
© Markus Knauß, 2008
Entwurfsmuster
Inhalt

Java Database Connectivity (JDBC)

Objektorientierte Konzepte

Template Method Pattern

Entwurfsmuster

Geburtstagskalender mit Entwurfsmustern

Zusammenfassung

Literatur und Links
26
© Markus Knauß, 2008
Entwurfsmuster
Beobachtungen
Die Abfolge der Schritte für den Datenbankzugriff via JDBC ist
immer gleich.

Verbindung zur Datenbank öffnen

Anweisung erstellen

Parameter initialisieren

Anweisung ausführen

Ergebnisse auswerten

Verbindung zur Datenbank schließen
Die Schritte unterscheiden sich in der ausgeführten Anweisung,
den Parametern und der Auswertung der Ergebnisse.
27
© Markus Knauß, 2008
Template Method
Zweck
Definiere einen Algorithmus in einer Methode. Delegiere einzelne
Schritte an erbende Klassen.
Entwurfsmuster
Die Verwendung einer Template Method ermöglicht es erbenden
Klassen, bestimmte Schritte eines Algorithmus zu überschreiben,
ohne die Struktur des Algorithmus zu ändern.
28
© Markus Knauß, 2008
Entwurfsmuster
Template Method
Motivation
Zum Beispiel Datenbankzugriff via JDBC:

Die Abfolge der Schritte für den Datenbankzugriff mit JDBC ist
immer gleich.

Die Inhalte der einzelnen Schritte, zum Beispiel die konkrete
Anweisung oder die Auswertung der Ergebnisse, sind
verschieden.
29

Invariante Teile eines Algorithmus sollen genau einmal
implementiert werden.

Gemeinsames Verhalten soll in einer Klasse zusammengefasst
werden.

Kontrolle der Erweiterungen durch Vererbung
Entwurfsmuster
© Markus Knauß, 2008
Template Method
Anwendbarkeit
30
© Markus Knauß, 2008
Template Method
Lösung
CreateStatement
Entwurfsmuster
DBStatement
+getStatement():String
+initParameter(stmt:PreparedStatement)
+evaluateResults(rs:ResultSet)
+execute()
PersonDB
ReadStatement
-id:int
UpdateStatement
DeleteStatement
SelectStatement
+create(person:IPerson):PersonDB
+read(id:int):PersonDB
+select(qbe:IPerson):List<PersonDB>
+read()
+update()
+delete()
NextPrimaryKeyStatement
31
© Markus Knauß, 2008
Entwurfsmuster
Template Method
Lösung
public final void execute() {
Connection con = null;
try {
con = DriverManager.getConnection(DB_URL);
PreparedStatement ps = con.prepareStatement(getStatement());
initParameter(ps);
ps.execute();
ResultSet rs = ps.getResultSet();
if (rs != null) {
while (rs.next()) {
evaluateResults(rs);
}
}
} catch (SQLException e) {
log.log(Level.SEVERE, e.getMessage(), e);
}
finally {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
log.log(Level.SEVERE, e.getMessage(), e);
}
}
}
}
DBStatement.java
32
public class PersonDB extends PersonBean implements IPerson, IDBObject {
private static final CreateStatement createStatement = new CreateStatement();
private static final ReadStatement readStatement = new ReadStatement();
private static final NextPrimaryKeyStatement nextPrimaryKeyStatement = new NextPrimaryKeyStatement();
//...
public static PersonDB create(IPerson person) {
nextPrimaryKeyStatement.execute();
int nextPK = nextPrimaryKeyStatement.getNextPrimaryKey();
createStatement.setId(nextPK);
createStatement.setFirstName(person.getFirstName());
createStatement.setLastName(person.getLastName());
createStatement.setDateOfBirth(person.getDateOfBirth());
createStatement.execute();
return new PersonDB(nextPK, person);
}
Entwurfsmuster
© Markus Knauß, 2008
Template Method
Lösung
public static PersonDB read(int id) {
readStatement.setId(id);
readStatement.execute();
return new PersonDB(
id, readStatement.getFirstName(),
readStatement.getLastName(), readStatement.getDateOfBirth());
}
//...
}
PersonDB.java
33

Gemeinsames Verhalten wird in einer Klasse gekapselt.

Der Kontrollfluss wird invertiert, die vererbende Klasse ruft
Methoden der erbenden Klasse auf.

Es muss klar sein, welche Methoden überschrieben werden
dürfen bzw. überschrieben werden müssen.
Entwurfsmuster
© Markus Knauß, 2008
Template Methode
Konsequenzen
34

Factory, Factory Method: nutzt Template Method zur
Objekterzeugung

Strategy: Kapselung eines Algorithmus
Entwurfsmuster
© Markus Knauß, 2008
Template Methode
Ähnliche und Verwandte Muster
35
© Markus Knauß, 2008
Entwurfsmuster
Inhalt

Java Database Connectivity (JDBC)

Objektorientierte Konzepte

Template Method Pattern

Entwurfsmuster

Geburtstagskalender mit Entwurfsmustern

Zusammenfassung

Literatur und Links
36
© Markus Knauß, 2008
Gamma et al. (1995)
Das Buch der „Gang of Four“: Design Patterns: Elements of
Reusable Object-Oriented Software, hat die Entwurfsmuster
bekannt gemacht und eine Entwurfsmuster-Bewegung initiiert.
Entwurfsmuster

Gamma, E., R. Helm, R. Johnson und J. Vlissides (1995):
Design Patterns: Elements of Reusable Object-Oriented
Software. Addison-Wesley.
In ihrem Buch dokumentieren die Autoren 23 Entwurfsmuster.
37
© Markus Knauß, 2008
Klassifizierung der Entwurfsmuster
Erzeugungsmuster
Entwurfsmuster
Verstecken die Erzeugung von Objekten, wodurch ein Programm
unabhängig von der Erzeugung, der Zusammensetzung und der
Initialisierung seiner Objekte wird.
Strukturmuster
Fassen Klassen und Objekte in größeren Strukturen zusammen,
wodurch ein zusammenhängendes System entsteht.
Verhaltensmuster
Kapseln Algorithmen und Zuständigkeiten, wodurch deren
Nutzung unabhängig von der Implementierung wird.
38
Gültigkeitsbereich
© Markus Knauß, 2008
Entwurfsmuster
Klassifizierung nach
Gamma et al. (1995)
Aufgabe
Erzeugungsmuster Strukturmuster
Factory Method
Adapter
klassenbasiert
(klassenbasiert)
Abstract Factory
Adapter
Builder
(objektbasiert)
Prototyp
Bridge
Singleton
Decorator
Facade
objektbasiert
Flyweight
Composite
Proxy
Verhaltensmuster
Interpreter
Template Method
Command
Observer
Visitor
Iterator
Memento
Strategy
Mediator
State
Chain of
Responsibility
39
© Markus Knauß, 2008
Entwurfsmuster
Dokumentation eines Entwurfsmusters

Name und Klassifizierung, Alternative Namen

Zweck, Motivation

Anwendbarkeit

Struktur, Teilnehmer, Interaktion

Konsequenzen

Implementierung, Beispiel-Programmcode, Bekannte
Verwendungen

Verwandte Entwurfsmuster
40
© Markus Knauß, 2008
Erzeugungsmuster
Abstract Factory: Definiert eine Schnittstelle, mit der Objekte
abstrakter Klassen erzeugt werden können. Die Implementierung
der abstrakten Klassen ist verborgen.
Entwurfsmuster
Builder: Trennt die Erzeugung eines Objekts von dessen
Repräsentation.
Factory Method: Deklariert eine Schnittstelle für die Erzeugung
von Objekten. Welche Objekte erzeugt werden, entscheidet die
implementierende Klasse.
Prototyp: Erzeugt Objekte durch kopieren eines Prototyps.
Singleton: Garantiert, dass von einer Klasse nur ein Objekt
erzeugt wird.
41
© Markus Knauß, 2008
Strukturmuster
Adapter: Passt die Schnittstelle einer Klasse an eine andere
Schnittstelle an.
Bridge: Entkoppelt eine Struktur von ihrer Implementierung.
Entwurfsmuster
Decorator: Erweitert ein Objekt um Funktionen/Zuständigkeiten.
Facade: Bietet eine einheitliche Schnittstelle für die Nutzung
eines Teilsystems.
Flyweight: Stellt Objekte zur gemeinsamen Verwendung zur
Verfügung.
Composite: Kombiniert Objekte in Baum-Strukturen.
Proxy: Kontrolliert den Zugriff auf ein Objekt.
42
© Markus Knauß, 2008
Verhaltensmuster
Command: Kapselt einen Algorithmus in einem Objekt.
Observer: Beobachtet den Zustand eines Objekts.
Entwurfsmuster
Visitor: Kapselt die Operationen, die auf einer Objektstruktur
ausgeführt werden, in einem Objekt.
Interpreter: Wertet Ausdrücke, die entsprechend einer
definierten Grammatik formuliert sind, aus.
Iterator: Bietet sequenziellen Zugriff auf die Elemente einer
Struktur.
Memento: Speichert den Zustand eines Objekts.
43
© Markus Knauß, 2008
Verhaltensmuster
Template Method: Definiert das Skelett eines Algorithmus und
bietet Erweiterungspunkte für die spezifische Anpassung.
Entwurfsmuster
Strategy: Kapselt die Implementierung eines Algorithmus in einer
Klasse.
Mediator: Definiert ein Objekt, welches das Zusammenspiel
mehrerer Objekte regelt.
State: Definiert das Verhalten eines Objekts abhängig von seinem
Zustand.
Chain of Responsibility: Entkoppelt den Aufrufer einer Routine
vom ausführenden Objekt.
44
© Markus Knauß, 2008
Entwurfsmuster
Inhalt

Java Database Connectivity (JDBC)

Objektorientierte Konzepte

Template Method Pattern

Entwurfsmuster

Geburtstagskalender mit Entwurfsmustern

Zusammenfassung

Literatur und Links
45
© Markus Knauß, 2008
Entwurfsmuster
Entwurfsmuster im
Geburtstagskalender

Singleton

Facade

Abstract Factory

Observer

Flyweight

Adapter
46
© Markus Knauß, 2008
Entwurfsmuster
Singleton
/**
* Holds an instance of this class.
*/
private static Application instance = null;
Klassenvariable speichert
einziges Objekt der Klasse.
/**
* Provides access to an instance of this class.
* @return
*/
public static Application getInstance() {
if (instance == null) {
instance = new Application();
}
return instance;
}
Auf die Klassenvariable kann
unterschiedlich zugegriffen
werden.
Application.java
Bei konkurrierenden Zugriffen
muss darauf geachtet werden,
dass nur ein Thread das Objekt
erzeugen kann.
47
© Markus Knauß, 2008
Entwurfsmuster
Singleton mit Thread-Synchronisation
/**
* Holds an instance of this class.
*/
private static Application instance = null;
/**
* Provides access to an instance of this class.
* @return
*/
public static Application getInstance() {
if (instance == null) {
synchronized (Application.class) {
if (instance == null) {
instance = new Application();
}
}
}
return instance;
}
Application.java
Double Checked Locking Muster
Threads werden nur
synchronisiert, wenn noch kein
Objekt erzeugt wurde.
Im synchronisierten Block kann
sich nur ein Thread befinden.
Im synchronisierten Block wird
noch einmal geprüft, ob bereits
ein Objekt erzeugt wurde.
48
© Markus Knauß, 2008
Entwurfsmuster
Singletons im Geburtstagskalender

Application.java

BirthdayIOFactory

UI.java

ActionRegistry.java

DBStatementRegistry.java
49
© Markus Knauß, 2008
Facade
Die Klasse PersonDB bietet einen einheitlichen Zugriff auf das
Teilsystem, das den Datenbankzugriff implementiert.
Registry
Entwurfsmuster
PersonDB
ValueType
DBStatement
+register(value:ValueType)
+get(key:String):ValueType
-id:int
+create(person:IPerson):PersonDB
+read(id:int):PersonDB
+select(qbe:IPerson):List<PersonDB>
+read()
+update()
+delete()
CreateStatement
DeleteStatement
DBStatementRegistry
ReadStatement
SelectStatement
UpdateStatement
50
© Markus Knauß, 2008
Entwurfsmuster
Abstract Factory

Skizzieren Sie die Beziehungen der Klassen BirthdayIO,
BirthdayIOFactory, CSVBirthdayIO,
CSVBirthdayIOFactory, DBBirthdayIO und
DBBirthdayIOFactory.

Wie wird ein Objekt einer Klasse erzeugt, die das Interface
BirthdayIO implementiert?

Welche Klassen muss ein Nutzer des IO-Teilsystems kennen,
um Geburtstage zu speichern bzw. zu laden?

Wie kann zwischen der Speicherung in einer Datenbank und
der Speicherung in CSV formatierten Dateien gewechselt
werden?
51
© Markus Knauß, 2008
Abstract Factory
BirthdayIO
+load():List<Birthday>
+store(birthdays:List<Birthday>)
Entwurfsmuster
DBBirthdayIO
CSVBirthdayIO
public static BirthdayIOFactory getInstance() {
if (instance == null) {
// instance = new CSVBirthdayIOFactory();
instance = new DBBirthdayIOFactory();
}
return instance;
}
Application.java
BirthdayIOFactory
+getIOProvider(): BirthdayIO
DBBirthdayIOFactory
CSVBirthdayIOFactory
Wechsel des IO-Teilsystems
durch ändern des IO-Factory-Objekts
52
© Markus Knauß, 2008
Observer
Die Klasse BirthdaysTableModel speichert die Geburtstage,
die in der Tabelle der graphischen Benutzungsschnittstelle
angezeigt werden.
Entwurfsmuster
Die Klasse Application speichert die Geburtstage.
BirthdaysTableModel
Application
Birthday
Wie wird ein Objekt der Klasse
BirthdaysTableModel über
eine Änderung der Daten in
einem Objekt der Klasse
Application informiert?
53
© Markus Knauß, 2008
Observer
PropertyChangeListener
+propertyChange()
Entwurfsmuster
BirthdaysTableModel
public void propertyChange(
PropertyChangeEvent evt) {
getBirthdays().clear();
Birthdays birthdays =
Application.getInstance().getBirthdays();
for (int birthdayIdx = 0;
birthdayIdx < birthdays.numberOfBirthdays();
birthdayIdx++) {
getBirthdays().add(birthdays.get(birthdayIdx));
}
fireTableDataChanged();
}
PropertyChangeSupport
+addPropertyChangeListener(listener:PropertyChangeListener)
+firePropertyChangeEvent()
Application
public void editBirthday(
Birthday oldBirthday, Birthday newBirthday) {
int indexOfOld =
birthdays.getIndexOf(oldBirthday);
birthdays.set(indexOfOld, newBirthday);
getPropertyChangeSupport().firePropertyChange(
"birthdays", oldBirthday, newBirthday);
}
54
© Markus Knauß, 2008
Flyweight
ValueType
Registry
Action
+register(value:ValueType)
+get(key:String):ValueType
AddAction
DeleteAction
Entwurfsmuster
EditAction
DBStatementRegistry
ActionRegistry
Die DBStatementRegistry
ist gleich aufgebaut.
ExitAction
HelpAboutAction
OpenAction
SaveAction
55
© Markus Knauß, 2008
Adapter (objektbasiert)
OpenAction
BirthdayIO
SaveAction
+load():List<Birthday>
+store(birthdays:List<Birthday>)
Entwurfsmuster
DBBirthdayIO
PersonDB
-id:int
+create(person:IPerson):PersonDB
+read(id:int):PersonDB
+select(qbe:IPerson):List<PersonDB>
+read()
+update()
+delete()
Ein Objekt der Klasse DBBirthdayIO adaptiert die Schnittstelle
der Klasse PersonDB auf die Schnittstelle des Interface
BirthdayIO.
56
© Markus Knauß, 2008
Entwurfsmuster
Geburtstagskalender
Weitere Entwurfsmuster:

Die Benutzungsschnittstelle ist entsprechend dem Model View
Controller Muster augebaut (UI-, Model- und Action-Klassen).

Der Algorithmus für die Erzeugung des Primärschlüssels für
das Speichern von Einträgen in der Datenbank kann mit
einem Strategy Muster implementiert werden.
Der Programmcode des Geburtstagskalenders steht auf der
Webseite zur Vorlesung zum Download zur Verfügung.
http://www.iste.uni-stuttgart.de/se/teaching/courses/muw/index.html
57
© Markus Knauß, 2008
Entwurfsmuster
Inhalt

Java Database Connectivity (JDBC)

Objektorientierte Konzepte

Template Method Pattern

Entwurfsmuster

Geburtstagskalender mit Entwurfsmustern

Zusammenfassung

Literatur und Links
58
© Markus Knauß, 2008
Vorteile und Nachteile
Entwurfsmuster sind wiederverwendbare Lösungen für
wiederkehrende Entwurfsprobleme auf Klassen- und Objektebene.
Entwurfsmuster
Entwurfsmuster, wie sie hier behandelt wurden, setzen ein
„solides“ Verständnis objektorientierter Konzepte voraus. Vor allem
Vererbung und Polymorphie müssen verstanden sein.
Die Verwendung von Entwurfsmustern macht die Teile eines
Programms unabhängiger voneinander, wodurch sie einfacher
austauschbar und wiederverwendbar sind.
Verständlicher wird ein Programm für den unerfahrenen
Entwurfsmuster-Anwender nicht.
59
© Markus Knauß, 2008
Entwurfsmuster
Praktische Anwendung
Im Rahmen dieses Vorlesungsteils wurde die praktische
Anwendung der Entwurfsmuster Singleton, Facade, Abstract
Factory, Observer, Flyweight, Adapter und Template Method im
Geburtstagskalender vorgestellt.
Die Anwendung und Implementierung des Template Method
Musters wurde praktisch geübt.
Der Programmcode des Geburtstagskalenders, in dem die Muster
implementiert sind, steht auf der Webseite zur Vorlesung zum
Download zur Verfügung.
60
© Markus Knauß, 2008
OO-Konzepte und Entwurfsmuster
Wichtige objektorientierte Konzepte, die für das Verstehen von
Entwurfsmustern notwendig sind, wurden besprochen.
Entwurfsmuster
Die Klassifizierung von Entwurfsmustern und ihre Dokumentation
nach Gamma et al. (1995) wurde vorgestellt.
Die 23 Entwurfsmuster, die in Gamma et al. (1995) dokumentiert
sind, wurden kurz vorgestellt.
61
© Markus Knauß, 2008
Entwurfsmuster
Ausblick
Muster gibt es für verschiedene Abstraktionsebenen eines
Programms, zum Beispiel für die Architektur oder den
Programmcode, aber auch für verschiedenste Einsatzzwecke, zum
Beispiel für Java Enterprise Anwendungen.
Architekturmuster: Bass, L., P. Clements und R. Kazman
(1998): Software Architecture in Practice. Addison Wesley
Longman, Inc.
Java Blueprints: http://java.sun.com/reference/blueprints/
Außerdem gibt es noch Anti-Patterns, RE-Patterns, UI-Patterns, ...
62
© Markus Knauß, 2008
Entwurfsmuster
Inhalt

Java Database Connectivity (JDBC)

Objektorientierte Konzepte

Template Method Pattern

Entwurfsmuster

Geburtstagskalender mit Entwurfsmustern

Zusammenfassung

Literatur und Links
63
© Markus Knauß, 2008
Literatur und Links
Das Buch der „Gang of Four“ mit den bekanntesten
Entwurfsmuster:
Entwurfsmuster

Gamma, E., R. Helm, R. Johnson und J. Vlissides (1995):
Design Patterns: Elements of Reusable Object-Oriented
Software. Addison-Wesley.
Wikipedia Artikel mit Links und Hintergrundinformationen für den
Einstieg ins Themengebiet (25.6.2008):

http://de.wikipedia.org/wiki/Entwurfsmuster
64
© Markus Knauß, 2008
Entwurfsmuster
Inhalt

Java Database Connectivity (JDBC)

Objektorientierte Konzepte

Template Method Pattern

Entwurfsmuster

Datenbankzugriff mit Entwurfsmustern

Zusammenfassung

Literatur und Links
65
Herunterladen