1 tit10aik @ ws 2012 software-engineering ii analyse- und entwurfsmuster
TRANSCRIPT
1 TIT10AIK @ WS 2012
Software-Engineering II
Analyse- und Entwurfsmuster
2 TIT10AIK @ WS 2012
Themenübersicht» Objektorientierung» Aspektorientierung» Vorgehensmodelle» UML» Analyse- & Entwurfsmuster» Objektorientiertes Testen» Versionsverwaltung» Refactoring» Labor (Praktischer Teil)
3 TIT10AIK @ WS 2012
Muster (Patterns)
» Beschreiben Lösungen zu häufig wiederkehrenden Problemen
» Muster bieten» jahrelang erprobte Lösungen die durch ihre Dynamik und Flexibilität herausstechen
» einheitliches Vokabular für die Arbeit im Team
4 TIT10AIK @ WS 2012
AnalysemusterAnalysemuster
Martin FowlerAddison-Wesley
386 Seiten
ISBN: 3-8273-1434-8 (Deutsch)
5 TIT10AIK @ WS 2012
Analysemuster
» Finden ihren Haupteinsatz in der Analysephase
» Bieten in der Praxis bewährte Modellierungen von Standardzusammenhängen aus spezifischen Domänen
6 TIT10AIK @ WS 2012
Beispiel: Muster „Party“
Fowler: Die Bezeichnung Party soll immer dann verwendet werden, wenn bei der Modellierung eine Generalisierung von Person und Organisation gesucht wird.
Bsp. aus der Domäne: Adressverwaltung
Adressbuch:In ihrem Adressbuch speichert eine Firma sowohl Privatpersonen als auch Organisationen. Beide Entitäten besitzen gleiche Eigenschaften: - Post-Anschrift - Telefon-Nummer - E-Mail-Adresse
Die Entität Party soll einen Oberbegriff für diese Entitäten bilden.
7 TIT10AIK @ WS 2012
Entwurfsmuster
Head First Design Patterns
Eric Freeman,Elisabeth Freeman,Kathy Sierra,Bert Bates
O‘Reilly
638 Seiten
ISBN: 0-5960-0712-4 (Englisch)
ISBN: 3-8972-1421-0(Deutsch)
8 TIT10AIK @ WS 2012
Entwurfsmuster
Design PatternsElements of ReusableObject-Oriented Software
„Gang of Four“
Addison-Wesley
395 Seiten
ISBN: 0-2016-3361-2 (Englisch)
(Die deutscheAusgabe wird nichtempfohlen)
9 TIT10AIK @ WS 2012
Entwurfsmuster
» Einsatz: Entwurfs- und Implementierungsphase
» Objektorientierte Klassenmodelle, die erprobte, generische Lösungen bieten
» Lösen wiederkehrende Probleme» Helfen, erweiterbaren und damit wieder verwendbaren Code zu schreiben
» Bieten Vokabular für Software-Ingenieure» Programmiersprachenunabhängig
10 TIT10AIK @ WS 2012
Das Singleton-Pattern
11 TIT10AIK @ WS 2012
Die Berufsakadie
» Situation: Es kann nur eine geben!» Es muss verhindert werden, dass mehrere Instanzen der Klasse erzeugt werden, da die Berufsakademie unser zentrales Verwaltungsobjekt darstellt
class x {
… ba.addSemester( new Semester( ‘TIT2005 ‘ ) );
}
class y {
… ba.addSemester( new Semester( ‘TIT2006‘ ) ); // Muss dieselbe
// Instanz sein!!!
}
12 TIT10AIK @ WS 2012
Ansatz: Statisches Attribut
» Die Instanz der Berufsakademie wird in einem statischen Attribut der Klasse gespeichert
Bei jedem Zugriff:
//---if( Berufsakademie.instance == null ) { Berufsakademie.instance = new Berufsakademie();}//---
Berufsakademie.instance.addSemester( … );
13 TIT10AIK @ WS 2012
Ansatz: Statisches Attribut
Bei jedem Zugriff:
//---if( Berufsakademie.instance == null ) { Berufsakademie.instance = new Berufsakademie();}//---
Berufsakademie.instance.addSemester( … );
» Das herkömmliche Instanzieren (new) wird nicht verhindert!
» Das Initialisieren kann leicht vergessen werden!
14 TIT10AIK @ WS 2012
Pattern: Singleton [I]
» Die Methode “getInstance“ liefert die eine Instanz der Klasse zurück
» Ein privater Konstruktor verbietet das externe Instanzieren der Klasse
» instance speichert die eine Instanz der Klasse als statisches Attribut
Erzeugt Instanz oder gibt sie zurück
PrivaterKonstruktor
Speichertdie Instanz
15 TIT10AIK @ WS 2012
Pattern: Singleton [II]
void someFunction(){ Berufsakademie.getInstance().addSemester( … );}
16 TIT10AIK @ WS 2012
Das Template Method-Pattern
17 TIT10AIK @ WS 2012
Benotung von Studenten I
» klausurenKorrigieren definiert einen festen Algorithmus:» Musterlösung bereitstellen» Die Klausuren aller Studenten mit der Musterlösung vergleichen» Dem Studiengangsleiter die Ergebnisse mitteilen
» Verschiedene Dozenten benoten Studenten unterschiedlich» Fair» Unfair» Alle kommen durch» Zufällig
fairness = { ‘fair‘, ‘unfair‘, ‘allekommendurch‘, ‘zufällig‘};
if( fairness == ‘fair‘ ) { …} else if( fairness == ‘unfair‘ ) {} …
18 TIT10AIK @ WS 2012
Benotung von Studenten II
» Problem dieses Ansatzes:» Stets, wenn ein neuer Dozententyp erscheint, muss die Klasse BADozent angepasst werden
» Die Methode klausurenKorrigieren wird unübersichtlich und unwartbar
19 TIT10AIK @ WS 2012
Design Prizipien I
» Codestellen isolieren, die sich häufig ändern können und flexibel für Änderungen zu machen» Trennung von statischen und dynamischen Programmstellen
20 TIT10AIK @ WS 2012
Pattern: Template Method
» Es werden Subklassen gebildet, die den variierenden Teil spezifisch implementieren
» Alles Statische bleibt in der Superklasse, der variable Algorithmus wird der Subklasse überlassen
21 TIT10AIK @ WS 2012
Template Method II
» Die Methode benote wird abstrakt, jede Subklasse muss diese Implementieren
» Das Grundgerüst des Algorithmus klausurenKorrigieren wird von der Klasse BADozent bereitgestellt (Musterlösung bereitstellen, alle Studenten benoten, Studiengangsleiter benachrichtigen)
22 TIT10AIK @ WS 2012
Template Method III
» Nun können alle Subklassen ihre eigene Implementierung realisieren
class ZufälligeNotenDozent extends BADozent { protected void benote( BAStudent st ) { st.setNote( Math.Random() * 5 + 1 ); }}
class UnfairerDozent extends BADozent { protected void benote( BAStudent st ) { st.setNote( Math.Random() * 2 + 4 ); }}
class AlleKommenDurchDozent extends BADozent { protected void benote( BAStudent st ) { st.setNote( Math.Random() * 3 + 1 ); }}
class FairerDozent extends BADozent { protected void benote( BAStudent st ) { st.setNote( Math.Random() * 5 + 1 ); }}
23 TIT10AIK @ WS 2012
Lustlos?
» Was, wenn manche Dozenten während der Korrektur die Lust verlieren und deshalb zu Beginn fairer korrigieren als gegen Ende?
» (Bspw. ab 50% der Studenten)» Der Dozent weiß aktuell nicht, wieviele Studenten noch kommen
24 TIT10AIK @ WS 2012
Hooks I
» Hooks sind Methoden in der Basisklasse, die nicht abstrakt sind, sondern einen leeren Methoden-Body besitzen
» Bei Bedarf kann eine Subklasse den Hook überschreiben, es ist ihr jedoch frei gestellt
25 TIT10AIK @ WS 2012
Hooks II
» BADozent wird um die Methoden korrekturStart und korrekturEnde erweitert
» Jeder beliebige Dozenten-Typ kann nun herausfinden, wieviele Studenten er korrigieren wird und so seine Bewertung durchführen
Ist nicht daraninteressiert, wieviele Studenten folgen Benotung abh. von
Anzahl
26 TIT10AIK @ WS 2012
Das Factory Method-Pattern
27 TIT10AIK @ WS 2012
Wer erstellt all diese Objekte?
» Viele Subklassen machen die Verwaltung schwierig
» Problem: Klassen werden an vielen Stellen des Codes erzeugt» Verlust der Übersicht » Es entstehen Abhängigkeiten
zwischen vielen Klassen» Bei Parametern im
Konstruktor: Anpassung des Konstruktors verherend
» Unwartbarer Code!
new FairerDozent(…)
new UnfairerDozent(…)new FairerDozent(…)
new AlleKommenDurchDozent(…)
new UnfairerDozent(…)
28 TIT10AIK @ WS 2012
So nicht!
Jeder kennt jeden! So verursacht die geringste Änderung ein Dilemma.
29 TIT10AIK @ WS 2012
Design Prizipien II
» Wenn möchlich nicht gegen konkrete Implementierungen sondern gegen Interfaces und abstrakte Klassen programmieren!
LaunischerDozent infoDozent;…infoDozent = new LaunischerDozent();infoDozent.klausuren…( … );
BADozent infoDozent;…infoDozent = new ???();infoDozent.klausuren…( … );
statt
besser
30 TIT10AIK @ WS 2012
Design Prizipien III
» Annahme: Die Art des Dozenten hängt von Fach, Geschlecht und Alter ab
» Statt hier eine Unterscheidung zu machen, verwenden wir eine Klasse, die uns die Instanzen erzeugt
BADozent infoDozent;…infoDozent = new ???();infoDozent.klausuren…( … );
besser
31 TIT10AIK @ WS 2012
Die Factory regelt das
» Die Fakultäten kennen die Factory und die abstrakte Klasse BADozent, die Factory kennt alle Dozenten-Typen
» Änderungen an den Dozenten-Typen müssen nur an der Factory gewartet werden
32 TIT10AIK @ WS 2012
CreateDozent
BADozent createDozent( int age, String subject, String gender ){ if( age > 65 ) { return new AlleKommenDurchDozent(); } if( subject.equals( “DB“ ) && gender.equals( “male“ ) ) { return new UnfairerDozent(); } if( subject.equals( “BWL“ ) ) { return new ZufälligeNotenDozent(); } return new FairerDozent();}
33 TIT10AIK @ WS 2012
Und die Fakultäten?
» Was, wenn Dozenten verschiedener Fakultäten unterschiedliche Gewichtungen bei der Charakterbildung der Dozenten haben?
» Bsp: » Informatik: Fair = {<40, weiblich, nicht Datenbanken}
» Maschinenbau: Fair = {>60, männlich, alle technischen Fächer}
34 TIT10AIK @ WS 2012
Pattern: Factory-Method» Jede Fakultät verwendet ihre eigene Factory, die nach
ihrem spezifischem Algorithmus die Dozenten klassifiziert
» Die Klasse DozentFactory ist nun abstrakt und zwingt die Subklassen, die Methode zu implementieren
35 TIT10AIK @ WS 2012
Erkannt?
» Wieder wurden die variablen Teile von den statischen getrennt» Die Factory-Methode ist eine spezielle Template-Methode
Potentiellvariabel
36 TIT10AIK @ WS 2012
Das State-Pattern
37 TIT10AIK @ WS 2012
Zustände I
38 TIT10AIK @ WS 2012
Zustände II» 5 Zustände
» Keine Klausur geschrieben» Klausur nicht best.» Nachklausur nicht best.» Fach best.» Fach nicht best.
» 3 Transitionen» durchgefallen» bestanden» krank am Klausurtag
39 TIT10AIK @ WS 2012
Ansatz: Zustandsattributclass BAStudent { private final static int KEINE_KLAUSUR_GESCHR = 0; private final static int KLAUSUR_NICHT = 1; private final static int NACHKLAUSUR_NICHT = 2; private final static int BESTANDEN = 3; private final static int NICHT_BESTANDEN = 4;
private int state = BAStudent.KEINE_KLAUSUR_GESCHR;
public void durchgefallen() {…} public void bestanden() {…} public void krank() {…}
}
40 TIT10AIK @ WS 2012
Methodenpublic void durchgefallen() { switch( state ) { case KEINE_KLAUSUR_GESCHR: state = KLAUSUR_NICHT; break; case KLAUSUR_NICHT: state = NACHKLAUSUR_NICHT; break; case NACHKLAUSUR_NICHT: state = NICHT_BESTANDEN; break; default: throw new Exception( “Nicht erlaubt!“ ); }}
public void bestanden() { …}
public void krank(){ if( state… ) { … } }
41 TIT10AIK @ WS 2012
Design Prinzipien?» Keine Abkapselung der
Programm-Teile, die variieren können
» Zustandsübergänge sind nicht explizit sondern inmitten der Contitional Statements vergraben
» Code ist Fehler-anfällig: ein neuer Zustand muss in allen Methoden gepflegt, kann jedoch übersehen werden
» Nicht objektorientiert
public void durchgefallen() { switch( state ) { case KEINE_KLAUSUR_GESCHR: state = KLAUSUR_NICHT; break; case KLAUSUR_NICHT: state = NACHKLAUSUR_NICHT; break; case NACHKLAUSUR_NICHT: state = NICHT_BESTANDEN; break; default: throw new Exception( “Nicht erlaubt!“ ); }}
42 TIT10AIK @ WS 2012
State Pattern I
» Interface State, definiert die Transitionsmethoden
» Für jeden möglichen Zustand existiert eine Subklasse von State» BestandenState» NachklausurNichtState» DurchgefallenState» KlausurNichtState» KeineKlausurState
» Die Klasse BAStudent delegiert den Methodenaufruf lediglich an das State-Objekt
43 TIT10AIK @ WS 2012
State Pattern II
» Alle State-Objekte haben eine Referenz auf das BAStudent-Objekt
» Durch die Methode setState können die Zustände Transitionen auslösen
44 TIT10AIK @ WS 2012
State Pattern IIIclass KeineKlausurState implements State {
BAStudent student;
public KeineKlausurState( BAStudent student ) { this.student = student; //jeder State bekommt eine Referenz des Studenten injiziert }
public void durchgefallen() { this.student.setState( … ); }
public void bestanden() { this.student.setState( … ); }
public void krank() { // der Zustand wird nicht geändert }
}
Zustands-transitionen
45 TIT10AIK @ WS 2012
State Pattern IVclass KeineKlausurState implements State {
BAStudent student;
public KeineKlausurState( BAStudent student ) { this.student = student; //jeder State bekommt eine Referenz des Studenten injiziert }
public void durchgefallen() { this.student.setState( … ); }
public void bestanden() { this.student.setState( … ); }
public void krank() { // der Zustand wird nicht geändert }
}
Zustands-transitionen
46 TIT10AIK @ WS 2012
State Pattern Vclass KeineKlausurState implements State {
BAStudent student;
public KeineKlausurState( BAStudent student ) { this.student = student; //jeder State bekommt eine Referenz des Studenten injiziert }
public void durchgefallen() { this.student.setState( … ); }
public void bestanden() { this.student.setState( … ); }
public void krank() { // der Zustand wird nicht geändert }
}
Zustands-transitionen
Die Klasse BAStudent hält alle möglichen Zustände vor
47 TIT10AIK @ WS 2012
State Pattern VIclass KeineKlausurState implements State {
BAStudent student;
public KeineKlausurState( BAStudent student ) { this.student = student; //jeder State bekommt eine Referenz des Studenten injiziert }
public void durchgefallen() { this.student.setState( this.student.GetKlausurNichtState() ); }
public void bestanden() { this.student.setState( this.student.GetBestandenState() ); }
public void krank() { // der Zustand wird nicht geändert }
}
48 TIT10AIK @ WS 2012
Weitere Patterns?
» Es gibt neben den hier vorgestellten noch viele nützliche Patterns
» Patterns werden in der Software-Entwicklung gerne und häufig eingesetzt» Beispiel: Java SDK API
» Factory Method: BorderFactory» Observer Pattern: Event-Listener» …