Refactoring-Tools in Eclipse

Aus Eclipse
Wechseln zu: Navigation, Suche

◄== zurück zur Übersichtsseite


Refactoring-Tools in Eclipse nehmen dem Programmierer einen großen Teil monotoner und fehleranfälliger Änderungsarbeit ab. Da Refactoring-Tools Programme sind, die Programme ändern, handelt es sich dabei um Metaprogramme.
Um die Konsistenz der Semantik zu testen, empfiehlt es sich, nach jedem Refactoring alle vorhandenen JUnit-Tests neu laufen zu lassen. Sollten diese scheitern, dann liegt möglicherweise ein Fehler im Refactoring-Tool vor.

Refactoring-Tools können ihrerseits Fehler enthalten. Im Sommersemester 2010 läuft am Fachbereich Programmiersysteme ein Fachpraktikum, welches sich mit dem Testen von Refactoring-Tools beschäftigt.

Standard-Tools

Abb. 1: Standard Refactoring-Tools der aktuellen Eclipse Version 3.5 (Galileo).

Die aktuelle Eclipse Version 3.5 (Galileo) bietet bereits etwa 30 Refactoring-Tools. Diese sind im JDT-Modul (Java Development Tooling) enthalten. Die Liste der verfügbaren Funktionen ist abhängig davon, ob ein Projekt, ein Package, eine Klasse, eine Methode oder eine Variable geändert werden soll. Es lässt sich im Grunde jedes Java-Element ändern. Für fast alle Elemente existieren die einfachsten und wichtigsten Refactoring-Tools 'Rename' und 'Move'.

Rename

Es lassen sich alle Arten von Variablen (lokale, Felder, Klassenvariablen und auch Konstanten) umbenennen. Aber auch für Projekte, Packages, Klassen und Methoden steht ein Rename-Refactoring-Tool bereit.

Move

Eine Klasse kann in ein anderes Package oder ein anderes Projekt verschoben werden. Dabei wird auch die entsprechende .java-Datei in das passende Verzeichnis verschoben.
Eine Methode kann in eine andere Klasse (und somit auch in ein anderes Package oder ein anderes Projekt) verschoben werden. Da das nicht immer sinnvoll ist (z.B. wenn es sich um einen Constructor oder eine vom Interface oder Oberklasse geerbte Methode handelt), verweigert das Move Refactoring-Tool in solchen Fällen die Aktion oder gibt zumindest eine Warnung aus.
Feld-Variablen lassen sich in eine andere Klasse verschieben. Bei lokalen Variablen sowie bei Methodenparametern ist das automatische Verschieben nicht sinnvoll. Beim Versuch wird das Tool nicht für die lokale Variable oder Methodenparameter, sondern "stillschweigend" für die übergeordnete Methode angeboten. Für die Methodenparameter existiert das Refactoring-Tool Change Method Signature.

Change Method Signature

Dieses Refactoring-Tool ändert nicht nur die Parameter einer Methode, den Rückgabeparameter und den Methodennamen, sondern auch den Access-Modifier: public, private, default oder protected.

Extract Method

Lager einen markierten Codeblock in eine eigene Methode aus und ersetzt alle Vorkommnisse des Codeblocks durch den Aufruf der neuen Methode. Die im Codeblock benötigten Parameter werden als Methodenparameter deklariert.

Extract Local Variable

Extrahiert aus einem beliebigen Ausdruck, wie z.B. 1+1 eine lokale Variable.

Extract Constant

Extrahiert aus einem beliebigen Ausdruck, wie z.B. 1+1 eine Feld-Konstante.

Inline

Fügt den Wert einer Variable anstelle der Variable ein.

int a = 1+1;
int b = a+1;

wird zu

int b = 1+1+1;

Fügt den Code einer Methode (Methodenkörper) anstelle des Methodenaufrufs ein.

Convert Anonymous Class to Nested Class

Wandelt einen Definition einer anonymen Klasse in eine Klasse, die in der selben Datei enthalten ist. Aus folgender anonymen Definition

button.addSelectionListener(new SelectionAdapter() {
  public void widgetSelected(SelectionEvent e) {
     if (button.getSelection())
	selectedProjectNames.add(projectName);
     else
        selectedProjectNames.remove(projectName);			
  }
});

wird in eine vollwertige Klassendefinition innerhalb der aktuellen Klasse umgewandelt.

Convert Local Variable to Field

Wandelt eine lokale Variable in eine Feld-Variable der Klasse um.

Extract Superclass

Erzeugt für die markierte Klasse eine Oberklasse, die die alte Oberklasse erweitert. Es werden zu der aktuellen Klasse passende Contructors erzeugt. Es lassen sich Felder und Methoden selektieren, die in die Oberklasse übernommen werden sollen.

Extract Interface

Erzeugt für die markierte Klasse ein Interface, die die alte Oberklasse erweitert. Es lassen sich Methoden selektieren, die in das Interface als abstrakte Methoden übernommen werden sollen.

Use Supertype Where Possible

Dieses Refactoring-Tool ändert die Definition aller Variablen vom Typ der selektierten Klasse auf den Typ einer Oberklasse (auswählbar). Wie der Name schon sagt, wird diese Änderung nur durchgeführt, wo es Sinn mach bzw. zulässig ist.

Push Down

Verschiebt Felder und Methoden aus einer Oberklasse in eine Subklasse.

Pull Up

Verschiebt Felder und Methoden aus einer Subklasse in die Oberklasse.

Extract Class

Kapselt einen markierten Codeblock in einer Klasse. Methodenaufrufe und Verwendungen von Variablen werden auf die neue Klasse umgeleitet.

Introduce Paramter Object

Kapselt die Parameter einer Methode in einer sogenannten Parameter-Klasse. Es wird eine neue Methode erzeugt, die statt der alten Parameter das neue Parameter-Objekt verwendet (es werden auch alle Methodenaufrufe ersetzt). Die alte Methode wird zum Delegator und wird als deprecated annotiert.

Intorduce Indirection

Erzeugt für eine Methode eine Delegator-Methode, die die ursprüngliche Methode aufruft. Das Empfängerobjekt der Original-Methode wird zum ersten Parameter der neuen. Mit der neuen Indirection-Methode können z.B. zusätzliche Checks oder Log-Ausgaben vor und nach dem Aufruf der alten Methode ausgeführt werden.

Introduce Factory

Angewendet auf einen Constructor-Aufruf (wie new MyClass()) erzeugt dieses Refactoring-Tool eine Factory Methode, die den Aufruf des Constructors enthält. Der Aufruf des Contructors wird durch den Aufruf der Factory-Methode ersetzt. Der Constructor wird als private deklariert. In Zukunft soll diese Klasse also nicht mehr über den Constructor, sondern nur über die Factory-Methode instantiiert werden.

Vorschau:

Abb. 2: Vorschau des Refactorings Introduce Factory.

Introduce Paramter

Wandelt einen Ausdruck oder einen Wert, der einer Variablen zugewiesen wird in einen Methodenparameter um. Alle Aufrufe der Methode werden ebenfalls umgewandelt, wobei der Ausdruck als Wert für den neuen Parameter übergeben wird.

Encapsulate Field

Ebenfalls ein interessantes Tool ist "Encapsulate Field", welches zu einer Feld-Variablen automatisch ein Satz Getter/Setter erzeugt.

Abb. 3: Der Refactoring-Dialog schlägt die Namen für Getter/Setter vor, abgeleitet vom Variablennamen. Es lassen sich noch einige Optionen, wie z.B. der Access Modifier, einstellen.

Abb. 4: Die Vorschau präsentiert den Vorher-Nachher-Zustand nebeneinander. Im Change-Tree können die betrofennen Änderungen verfolgt und selektiv deaktiviert werden.

Abb. 5: Nach Bestätigung der Vorschau wird ein neuer Satz Feld-Accessoren generiert.

▲___zum Seitenanfang

Generalize Declaring Type

Ähnlich wie Use Supertype Where Possible wird der Typ eines Methoden-(Rückgabe-)Parameters oder einer Variablen ersetzt durch einen der Obertypen (auswählbar). Die Änderungen gelten aber nur für die aktuelle Klasse und man startet nicht von der Klasse, deren Typ ersetzt werden soll, sondern von einer Variablen-Definition oder einem Methoden-(Rückgabe-)Parameter.

Infer Generic Type Arguments

Versucht bei allen nicht-generischen Verwendungen von Listen und Collections den generischen Typ zu bestimmen.

Create Script

Erzeugt aus den durchgeführten Refactorings in der Refactoring-History einen Refactoring-Script, der später oder in einer anderen Eclipse-Instanz ausgeführt werden kann. Dies wird mit Apply Script ausgeführt.

History

Zeigt die Refactoring-History

Benutzerführung

Die Benutzerführung ist bei allen Refactoring-Tools ähnlich, wie hier am Beispiel von 'Rename' demonstriert:

  1. Abb. 6: Hier soll die Feld-Variable name in nachname umbenannt werden.

  2. Abb. 7: Nach der Markierung der Variable im Editor lässt sie sich mit dem Shortcut SHIFT+ALT+R schnell umbenennen, indem man einfach den neuen Namen im gelben Bereich tippt und mit Enter bestätigt. In der Outline funktioniert Rename nur per Dialog (s. Abb. 9)

  3. Abb. 8: Alternativ zum Shortcut - ein Rechtsklick auf die Variable im Editor oder in der Outline zeigt nach der Auswahl des Menüs Refactor alle nur für Variablen verfügbaren Refactoring-Tools an. Im anderen Kontext, z.B. Klasse oder Methode, sieht die Liste zum Teil anders aus. Auswahl hier Rename.

  4. Abb. 9: Die Umbenennung per Dialog, bietet mehr Optionen (z.B. 'Update references').

  5. Abb. 10: Die Blick in die Vorschau zeigt einen Vorher-Nachher-Vergleich

  6. Abb. 11: Die Feld-Variable name wurde in nachname umbenannt.

  7. Mit der Undo-Funktion (Menü Edit|Undo <Refactoring-Tool-Name>) können alle durchgeführten Änderungen in einem Schritt rückgängig gemacht werden.


◄== zurück zur Übersichtsseite