Inhalt | Abbildung | Source | OO-Designkurs | |||
|< | < | > | >| | Generated by CoCoDiL |
void myMethod(){ if (widgetId == #F0F898){ "ist Widget sichtbar" tueEtwas(); } |
daraus wird:
boolean isWidgetVisible(){ return widgetId == #F0F898 } void myMethod(){ if (isWidgetVisisble){ tueEtwas(); } } |
Was ist passiert?
Do not comment bad code, rewrite it |
Bemerkung: Ein Coverageanalyse-Tool ist ein unentbehrliches Hilfsmittel für Tests. Es stellt fest, welche Klassen bzw. Methoden, wie oft und ggf. mit welchen Parametern aufgerufen worden sind. So kann man feststellen, welcher Bereich des Source Codes noch nicht ausreichend getestet worden ist. Einfache Coverageanalyse - Tools erkennen nicht welche Verzweigungen (z.B IFThenElse Block) innerhalb einer Methode aufgerufen worden ist. Deshalb verwende kleine Methoden, ohne groessere Verzweigungen
* Reusability through self encapsulation Mein Lieblingsartikel aus dem Plop1 Buch von Ken Auer. Es geht um grundsaetzliche Vorgehensweise beim Design einer Klasse |
Extrahiere Methode ohne lokale Variable
void printOwing(){ Enumeration e = _orders.elements(); double outstanding = 0.0 ; // print banner System.out.println ("*************************"); System.out.println ("***** Customer Owes *****"); System.out.println ("*************************"); // calculate outstanding while (e.hasMoreElements()){ Order each = (Order) e.nextElement(); outstanding += each.getAccount(); } // printDetails System.out.println("name:" + _name); System.out.println("amount:" + outstanding); } |
Zuerst wird printBanner extrahiert, da in diesem Teil keine lokalen Variablen sind, ist diese Aktion besonders trivial.
void printOwing(){ Enumeration e = _orders.elements(); double outstanding = 0.0 ; printBanner(); // calculate outstanding while (e.hasMoreElements()){ Order each = (Order) e.nextElement(); outstanding += each.getAccount(); } // printDetails System.out.println("name:" + _name); System.out.println("amount:" + outstanding); } void printBanner(){ System.out.println ("*************************"); System.out.println ("***** Customer Owes *****"); System.out.println ("*************************"); } |
Extrahiere Methode mit lokale Variablen
Jetzt wird printDetails extrahiert. Dabei wird eine lokale Variable outstanding benutzt, die als Parameter übergeben wird
void printOwing(){ Enumeration e = _orders.elements(); double outstanding = 0.0 ; printBanner(); // calculate outstanding while (e.hasMoreElements()){ Order each = (Order) e.nextElement(); outstanding += each.getAccount(); } printDetails(outstanding) } void printBanner(){ System.out.println ("*************************"); System.out.println ("***** Customer Owes *****"); System.out.println ("*************************"); } void printDetails( double outstanding ){ System.out.println ("name:" + _name); System.out.println ("amount" + outstanding); } |
Jetzt wird calculate outstanding extrahiert. Die lokale Variable outstanding kann in extrahierten Teil definiert werden. Da sie von printDetails noch gebraucht wird, muss sie als returnWert zurückgegeben werden
void printOwing(){ printBanner(); double outstanding = getOutstanding(); printDetails(outstanding) } void printBanner(){ System.out.println ("*************************"); System.out.println ("***** Customer Owes *****"); System.out.println ("*************************"); } void printDetails( double outstanding ){ System.out.println ("name:" + _name); System.out.println ("amount" + outstanding); } double getOutstanding(){ Enumeration e = _orders.elements(); double result = 0.0; while (e.hasMoreElements()){ Order each = (Order) e.nextElement(); result += each.getAmount(); } return result ; } |
Refactoring Extract Method |
Eine einheitliche Benennung der Methoden vereinfacht die Lesbarkeit des Codes. Dirk Riehle hat im JavaReport eine * Typsierung von Methoden, je nach Verwendungszweck, sowie eine Einteilung nach * Methoden Eigenschaften vorgeschlagen. Jeder Methodentyp wird durch ein bestimmtes Prefix im Namen gekenndzeichnet. Hier ein Link zum * Original.
Einige Methoden lassen sich trotz grosser Anstrengungen nicht extrahieren. Dies liegt meist daran, daß sehr viele lokale Variablen verwendet werden, und innerhalb der Methode verschachtelte Kontrollstrukturen und Returns sind. In diesen Fällen hilft es, die Methode durch eine Klasse zu ersetzen. Da in dieser Klasse alle lokalen Variabeln der komplexen Methode als Instanzvariablen umgewandelt sind, lässt sich die Klasse leicht refaktorisieren.
Refactoring Replace Method with Method Object |
Inhalt | Abbildung | Source | OO-Designkurs | |||
|< | < | > | >| | Generated by CoCoDiL |