Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Refactoring To Patterns Generalization Patterns. Einführung Ziel spezifisches Code -> allgemeingültigeres Code Motivation Beseitigung von mehrfach vorhandenes.

Ähnliche Präsentationen


Präsentation zum Thema: "Refactoring To Patterns Generalization Patterns. Einführung Ziel spezifisches Code -> allgemeingültigeres Code Motivation Beseitigung von mehrfach vorhandenes."—  Präsentation transkript:

1 Refactoring To Patterns Generalization Patterns

2 Einführung Ziel spezifisches Code -> allgemeingültigeres Code Motivation Beseitigung von mehrfach vorhandenes Code Vereinfachung und Verdeutlichung vom Code

3 Generalization Patterns 7 Patterns Form Template Method Extract Composite Replace One/Many Distinctions with Composits Replace Hard-Coded Notifications with Observer Unify Interfaces with Adapter Extract Adapter Replace implicit Language with interpreter

4 Form Template Method Grundprinzip Zwei Methoden in den Unterklassen führen ähnliche schritte in der selben Reihenfolge aus. Generalisiere diese Methoden folgender maßen: 1. Extrahiere die einzelnen Schritte zu separaten Methoden mit gleichen Signaturen 2. Verlege diese generalisierten Methoden nach oben, um ein Template Methode zu bilden

5 Form Template Method Grundidee Implementiere den unveränderlichen (invarianten) Teil eines Algorithmen nur einmal und überlasse die Implementierung des veränderlichen (varianten) Teils den Unterklassen. Unveränderlicher Teil des Algorithmus umfasst: Die aufzurufenden Methoden und die Reihenfolge deren Aufrufs Die abstrakten Methoden, die von den Unterklassen überschrieben werden müssen Die Hook Methoden

6 Form Template Method

7 public class Flug extends ReiseLeistung {... private Hashtable klasse2Frei = new public boolean flugPlatzBuchen (int anzahl, String klasse){ //frage die Anzahl der noch freien Sitzplaetze in der gegebenen Klasse ab int frei = klasse2Frei.get(klasse); //wenn es nicht genuegend freie Plaetze gibt if (anzahl > frei) return false; //wenn es genuegend freie Plaetze gibt //aktualiesiere die Anzahl der noch freien plaetze klasse2Frei.put( klasse, frei – Anzahl ); //Druecke Tickets aus druckFlugTicketsAus(anzahl, klasse); return true; }... }

8 Form Template Method public class Hotel extends ReiseLeistung {... private Hashtable kategorie2Frei = new public boolean zimmerBuchen (int anzahl, String kategorie){ //frage die Anzahl der noch freien Zimmer in der gegebenen Kategorie ab int frei = kategorie2Frei.get(kategrie); frei -= getInReperatur(kategorie); //wenn es nicht genuegend freie Zimmer gibt if (anzahl > frei) return false; //wenn es genuegend freie Zimmer gibt //aktualiesiere die Anzahl der noch freien Zimmer kategorie2Frei.put(kategorie,frei-anzahl); //Druecke Tickets aus druckZimmerReservierungAus(anzahl,kategorie); return true; }... }

9 Form Template Method

10 public class ReiseLeistung {... public abstract int getFreieKapazitaet (String kategrie); public abstract void updateFreieKapazitaet (String kategorie,int neuKapazitaet); public abstract void druckLeistungsBeleg (int anzahl, String kategorie);... public boolean buchen (int anzahl, String kategorie){ int frei = getFreieKapazitaet(kategrie); if (anzahl > frei) return false; updateFreieKapazitaet(kategorie,frei-anzahl); druckLeistungsBeleg(anzahl, kategorie); return true; }... }

11 Form Template Method Prozedur 1.Compose Method in den Unterklassen anwenden, um identische Methoden (gleiche Signatur und Implementierung) und unique Methoden (Methoden die unterschiedliche Signatur/Implementierung in jeder Unterklasse haben) zu erzeugen. 2.Pull Up Method an allen identischen Methoden anwenden, um diese Methoden in die Basisklasse zu verlagern. 3.Rename Method an allen unique Methoden anwenden, um identische Signatur in jeder Unterklasse herzustellen. 4.Rename Methode anwenden, falls die zukünftige Template-Methode in allen Unterklassen gleiche Signatur besitzt. 5.Pull Up Method anwenden, um die Template-Methode in die Basisklasse zu verlagern und abstracte Methoden für unique Methoden in der Basisklasse definieren.

12 Form Template Method Vorteile Beseitigt mehrfach vorhandenes Code in Unterklassen durch Verlagerung vom gemeinsamen, unveränderlichen Teil des Algorithmus in die Basisklasse Vereinfachung des Codes und bessere Kommunikation durch Verdeutlichung der im generischen Algorithmus enthaltenen Schritte Vereinfachte Anpassung in den Unterklassen durch Überschreibung der abstrakten Methoden in den Unterklassen Nachteil Komplizierteres Design, wenn Unterklassen viele abstrakte Methoden überschreiben müssen

13 Extract Composite Grundprinzip Die Unterklassen in einer Hierarchie implementieren das selbe Composite Design Pattern. Extrahiere eine Basisklasse, welche das Composite Design Pattern implementiert und leite die Unterklassen von dieser neuen Klasse ab.

14 Extract Composite Grundidee Dieses Refactoring ist sehr ähnlich dem Extract Superclass Refactoring von Fowler. Die gemeinsame Eigenschaft der Unterklassen ist in diesem Fall das Composite DP. Unterklassen in einer Hierarchie speichern häufig Referenzen auf andere Objekte in Collections und bieten verschiedene Methoden für deren Manipulation an. Wenn die gespeicherten Objekte, wiederum der selben Hierarchie angehören, kann meistens mehrfach vorhandenes Code durch das Anwenden von Composite DP beseitigt werden.

15 Extract Composite

16 public class LinkTag extends Node {... private Vector children = new... public void addChild(Node child) {... } public boolean hasChild(Node child) {...}... public String toTextString (){ String text = ; for (Node child : children) text += child.toTextString(); return text; }... }

17 Extract Composite

18 public class CompositeNode extends Node {... private Vector children = new... public void addChild(Node child) {... } public boolean hasChild(Node child) {...}... public String toTextString (){ String text = ; for (Node child : children) text += child.toTextString(); return text; }... } public class LinkTag extends CompositeNode { …

19 Extract Composite Prozedur 1.Erstelle eine neue Klasse, welche im Züge dieser Refactoring die Implementierung des Composite Design Patterns wird. 2.Leite alle Child-Container Unterklassen von dieser neuen Klasse ab. 3.In den Unterklassen finde alle identischen oder ähnlichen Methoden zur Behandlung von Kindern. Wenn nötig wende Rename Methode an, um gleiche Signatur in allen Unterklassen herzustellen. 4.Wende in den Unterklassen Pull Up Field an, um das Container Feld in die Basisklasse zu verlagern. Wende dann Pull Up Method an, um die identischen Methoden in die Basisklasse zu ziehen. 5.Wende überall, wo es möglich ist, Substitute Algorithm an, um die nicht identischen Methoden, welche nur teilweise den gleichen Code besitzen zu identischen Methoden umzwanderen und wiederhole Shritt 4. Wenn dies nicht möglich sein sollte verwende Form Template Method an.

20 Extract Composite Vorteile Beseitigt mehrfach vorhandenes Code für die Behandlung von Speichern und der Manipulation von Kindern in den Unterklassen Verdeutlicht die Tatsache, dass die Behandlung von Kinderen in zukunftigen Unterklassen ebenfalls geerbt werden kann

21 Replace One/Many Distinctions with Composite Grundprinzip In einer Klasse existieren unterschiedliche Methoden (oder Code-Stücke) für die Durchführung der gleichen Aufgabe an einem Objekt oder an einer Sammlung (Collection) von dem selben Objekt. Verwende eine Composite Klasse, um die Behandlung von einem Objekt und einer Sammlung des selben Objekts zu vereinheitlichen.

22 Replace One/Many Distinctions with Composite Grundidee Vereinheitliche die Bearbeitung von Single oder Collection Objekten und damit den Code des Servers sowie des Clienten. Keine Unterscheidung zwischen ein oder mehreren Objekten Entfernung des duplizierten Codes in vielen Stellen.

23 Replace One/Many Distinctions with Composite

24 public class Markler {... public void verkaufeEigentum(WohnEinheit eigentum, String kaeufer){ eigentum.setBesitzer(Kaeufer); einkunft += eigentum.getPreis()*0.1; }... public void verkaufeEigentuemer(Vektor eigentuemer, String kaeufer){ for (WohnEinheit eigentum : eigentuemer) { eigentum.setBesitzer(Kaeufer); einkunft += eigentum.getPreis()*0.1; }... }

25 Replace One/Many Distinctions with Composite

26 public class WohnKomplex { public WohnKomplex(Vector ws){ einheiten = ws; } public Vector getWohnEinheiten(){ return einheiten; } public void setBesitzer(String kaeufer){ for (WohnEinheit eigentum : einheiten) eigentum.setBesitzer(Kaeufer); } public int getPreise(String kaeufer){ int preis = 0; for (WohnEinheit eigentum : einheiten) preis += eigentum.getPreis(); return preis; } private Vector einheiten; }

27 Replace One/Many Distinctions with Composite public class Markler {... public void verkaufeEigentum(WohnEinheit eigentum, String kaeufer){ eigentum.setBesitzer(Kaeufer); einkunft += eigentum.getPreis()*0.1; }... }

28 Replace One/Many Distinctions with Composite Prozedur 1.Erzeuge eine neue Klasse, welche im Züge dies Refactorings zur Implementierung des Composite Design Patterns wird. Diese Klasse bekommt ein Collection als Argument seines Constructors und stellt die entsprechende get Methode zur Verfügung. 2.Erzeuge eine neue Instanz dieser Klasse in der Client-Klasse, in der Methode, die das Collection als Argument hat und überarbeite den Code, so dass nun diese Composite-Klasse anstelle von Collection verwendet wird. 3.Wende Extract Method an, um den Collection Handling Code in eine neue public Methode zu ziehen. 4.Benutze Move Method, um diese Methode in die Composite Klasse zu verlagern. 5.Ändere die Methode, welche die Sammlung von Objekten behandelte, so, dass sie nun aus einer einzigen Zeile besteht, welche die Single Object Methode aufruft und ihr als Argument das neue Composite Objekt übergibt. 6.Wende Inline Method an. 7.Wende Encapsulate Collection in der Composite Klasse an: erstellt eine add(..) Methode und verändert die get Methode so, dass nun eine unveränderliche Collection zurück gegeben wird

29 Replace One/Many Distinctions with Composite Vorteile Beseitigt mehrfach vorhandenen Code für die Behandlung von einem oder mehreren Objekten. Vereinheitlicht den Zugriff der Client-Klassen: Eine Client-Klasse benutzt die selbe Methode, unabhängig davon ob sie ein oder eine Sammlung von dem selben Objekt als Argument benutzen will. Unterstützt einen besseren Umgang mit Collection Objekten: Die Klienten können durch den Aufruf einer einzigen Methode das Ergebnis der Bearbeitung von einem Objekt-Baum zurück erhalten. Nachteil Typüberprüfung zur Laufzeit ist bei der Erstellung vom Composit Objekt notwendig Erhöhtes Risiko zur Laufzeit (Generics)

30 Replace Hard-Coded Notifications with Observer Grundprinzip Die Unterklassen sind hard-codiert, um beim Auftretten eines bestimmten Ereignisses eine einzige Instanz einer anderen Klasse zu benachrichtigen. Beseitige die Unterklassen, indem die Basisklasse so erweitert wird, dass sie eine oder mehrere Instanzen jeder Klasse benachrichtigt kann, welche eine bestimmte Observer Interface implementiert.

31 Replace Hard-Coded Notifications with Observer Grundidee Verwende das Observer Design Pattern: Erstelle ein Observer Interface und erweitere die Basisklasse zu einer Subjekt-Klasse und die zu benachrichtigenden Klassen zu den Observer-Klassen.

32 Replace Hard-Coded Notifications with Observer

33

34 Prozedur 1.Falls eine der Notifier Unterklassen zusätzlich zu der Benachrichtigungsaufgabe noch weitere receiver-speziefische Bearbeitungen durchführt, verlagere diese Arbeit in die Receiver Klasse durch die Anwendung von Move Method. 2.Erstelle ein Observer Interface, durch Anwendung von Extract Interface an einer der Receiver-Klassen. 3.Lass jede Receiver-Klasse das neu erzeugte Observer Interface implementieren. Ändere alle Notifier Unterklassen, so dass sie nur durch das Observer Interface mit ihren Receivern kommunizieren. 4.Wende Pull Up Method an allen Notifier Unterklassen, um die Notification-Methoden nach oben in die Basisklasse zu ziehen. Die Basis-Klasse ist nun eine Subjekt-Klasse. 5.Ergänze die Basisklasse mit Methoden für die Registrierung von Observern. 6.Überarbeite alle Observer, damit sie sich bei der Basis-Klasse (Subjekt) registrieren und nur mit ihr kommunizieren.

35 Replace Hard-Coded Notifications with Observer Vorteile Lose Koppelung zwischen der Subject- und der Observer-Klasse. Unterstützt einen oder mehreren Observern. Nachteile Führt zu einer komplizierteren Design, besonders beim Cascading Notifications. Es kann zu Speicherplatzproblemen führen, falls die Referenzen der Observer von der Subjekt-Klasse nicht gelöscht werden.

36 Unify Interfaces with Adapter Grundprinzip Die Client-Klasse interagiert mit zwei verschiedenen Server-Klassen, mit unterschiedlichen Schnittstellen. Vereinheitliche die Klient-Server-Schnittstelle mit Hilfe eines Adapters.

37 Unify Interfaces with Adapter Grundidee Dieses Refactoring ist im Grunde die Anwendung des Adapter [DP] und kann immer angewendet werden wenn: Zwei Klassen das gleiche tun aber dafür unterschiedliche Schnittstellen anbieten. Der Code in der Client-Klasse kann durch die Vereinheitlichung wesentlich vereinfacht werden Die Schnittstelle einer beiden Klassen kann nicht einfach an die andere angepasst werden (Bibliotheken, Frameworks,…) Die Grundidee ist gleiche die unterschiede in den Schnittstellen durch einen Adapter.

38 Unify Interfaces with Adapter

39

40 Prozedur 1.Extract Interface in der Klasse anwenden, deren Schnittstelle von der Client- Klasse bevorzugt wird. Dadurch wird die gemeinsame Schnittstelle erzeugt. 2.Überarbeite die ursprugliche Klasse und ersetze alle Referenzen in deren Methoden auf die Klasse selbst durch das neu erzeugtes Interface. 3.In der Client-Klasse Extract Class anwenden, um einen primitiven Adapter für die zweite Server-Klasse zu erstellen. 4.Die Client-Klasse so überarbeiten, dass überall anstelle von der zu adaptierenden Klasse der Adapter verwendet wird. 5.In der Client-Klasse Extract Method überall dort anwenden, wo der Client die selbe Adaptee Methode anwendet, um eine Adaptee Aufruf-Methode zu erzeugen. 6.Alle diese Adaptee Aufruf-Methoden mit Move Method, in den Adapter verlagern. 7.Die Adapter-Klasse muss nun das im Schritt 1 erzeugte Interface implementieren. 8.Überarbeite die Client-Klasse, so dass sie nur noch das Interface als einheitliche Schnitte verwendet.

41 Unify Interfaces with Adapter Vorteile Beseitigung von mehrfach vorhandenen Code durch Vereinheitlichung der Kommunikation zwischen der Client- und verschiedenen Server- Klassen durch das gleiche Interface. Vereinfachung des Codes in der Client-Klasse. Nachteile Führt zu einer unnötig komplizierteren Design, wenn die Schnittstellen der Serverklassen direkt angepasst werden können.

42 Extract Adapter Grundprinzip Eine Klasse ist Adapter für mehre unterschiedliche Versionen einer klassen, eines Komponenten, eines API oder eines anderen Entity. Extrahiere einen Adapter für jede einzelne Version.

43 Extract Adapter Grundidee Häufig muss eine Software mehrere Versionen eines Komponenten, einer Bibliothek oder API unterstutzen. Der Code, welche diese Aufgabe übernimmt muss nicht zwangsweise alle unterschiede an eine Stelle beweltigen. Die Grundidee dabei ist: Erstelle für jede Version jeweils eine neue Adapterklasse zur Verfügung.

44 Extract Adapter

45 Unify Interfaces with Adapter

46 Extract Adapter Prozedur Falls die jeweils richtige Methoden in der ursprünglichen Adapter Klasse durch vielen Fallunterscheidungen gewählt werden, können die eigenständigen Adapter-Klasse für die jeweilige Version durch die Anwendung von Replace Conditional with Polymorphism erstellt werden. Sollte dies nicht der Fall sein und die Adapter-Klasse version-spezifische Variablen und Methodenargumente unterstützen, müssen folgende Schritte durchgeführt werden: 1.Wende Extract SubClass oder Extract Class in der Adapter-Klasse an, um eine neue Adapter-klasse für jede spezifische Version zu erstellen. 2.Wende Move Method und Move Field an, um die entsprechend Felder und Methoden in die jeweilige neue Adapter-Klasse zu verlagern. 3.Beseitige dublikaten Code in den neuen Adapter-Klassen mittels Pull Up Method und Form Template Method.

47 Extract Adapter Vorteile Isoliert die Unterschiede in verschiedenen Versionen des benutzten Komponenten Deutliche Verantwortungsaufteilung zwischen den Klassen, die jeweils nur für eine einzige Version zuständig sind. Vermeidet sich häufig verändernden Code. Nachteile Kann eine wichtige Funktionalität vor der Client-Klasse verbergen, wenn diese Funktionalität in der gerade angewandten Adapter nicht vorhanden ist.

48 Replace implicit Language with interpreter Grundprinzip Zahlreiche Methoden in einer Klasse kombinieren Elemente einer spezifischer Sprache. Definiere neue Klassen für die jeweiligen Elemente dieser spezifischen Sprache, so dass diese Elemente zu interpretierbare Ausdrucke kombiniert werden können.

49 Replace implicit Language with interpreter Grundidee In einer Klasse existieren zahlreiche Versionen einer Methode für die Ausführung einer bestimmten Aufgabe, welche sich darin unterscheiden, dass sie verschiedene Kombinationen einer Gruppe von Elementen als Argumentenliste haben. Grundidee ist die Definition einer interpretierbare Sprache, deren Elemente als gültige Ausdrucke ausgewertet werden können, um beliebige Kombinationen zu verwirklichen.

50 Replace implicit Language with interpreter

51

52 Vorteile Unterstützt die Kombination von Sprachelementen besser als eine implizierte Sprache. Kein neuer Code wird benötigt, um neue Kombinationen zu bearbeiten. Erlaubt die Umstellung der Konfiguration zur Laufzeit. Nachteile Relative hoher Aufwand am Anfang, um neue Sprachelemente und die dazugehörige Grammatik zu implementieren und die Client-Klassen dementsprechend anzupassen. Sehr langes Programmieren bei besonders komplexen Sprachen. Unnötige Komplikation des Designs, wenn die spezifische Sprache zu einfach ist.


Herunterladen ppt "Refactoring To Patterns Generalization Patterns. Einführung Ziel spezifisches Code -> allgemeingültigeres Code Motivation Beseitigung von mehrfach vorhandenes."

Ähnliche Präsentationen


Google-Anzeigen