17.7 Refactoring
Mit Refactoring wurde in Visual Studio 2005 erstmals eine Technik eingeführt, die bisher nur durch das Einbinden zusätzlicher Tools zu nutzen war. Refactoring ist hauptsächlich dann sinnvoll einzusetzen, wenn die Software bereits fertig ist. Sie können mit dieser Technik Änderungen am Code vornehmen, ohne dass sich das Verhalten der Anwendung ändert.
Sie werden mir beipflichten, dass während des Entwicklungsprozesses insbesondere größerer und komplexerer Software oft der Überblick über den Code verloren geht. Codepassagen wiederholen sich, Methoden werden zu komplex, weil der Modularisierung des Programmcodes zu wenig Aufmerksamkeit geschenkt wird, Variablennamen sind unpassend vergeben – typische Phänomene bei vielen Projekten. Mit der Technik des Refactorings können Sie dazu beitragen, dass der Code überschaubarer und klarer strukturiert wird. Dazu bieten sich mehrere Verfahren an:
- Methode extrahieren
- Bezeichner umbenennen
- Felder einkapseln
- Schnittstellen extrahieren
- Lokale Variable auf Parameter heraufstufen
- Parameter entfernen
- Parameter neu anordnen
In den deutschsprachigen Versionen von Visual Studio 2012 werden Sie den Begriff »Refactoring« nicht finden. Er wurde – bedauernswerterweise – in »Umgestaltung« übersetzt. Unter der deutschen Übersetzung sollten Sie nach Bedarf auch in der .NET-Dokumentation nachschlagen.
Ich möchte hier nicht auf jede der aufgeführten Möglichkeiten detailliert eingehen, sondern nur die am häufigsten benutzten vorstellen.
17.7.1 Methode extrahieren
Der Sinn der Modularisierung ist es, viele kleine Methoden zu haben, die leichter zu überblicken und besser zu verstehen sind als lange und bildschirmfüllende. Der Methodenbezeichner sollte zudem so gewählt werden, dass man sofort weiß, was die Aufgabe der Methode ist. Gerät Ihnen bei der Entwicklung mal eine Methode »aus den Fugen«, müssen Sie die Codezeilen finden, die zusammengehören. Anschließend schneiden Sie diese aus und setzen sie in eine neue Methode ein. An die Stelle der Codezeilen, die Sie ausgegliedert haben, setzen Sie den Aufruf der neuen Methode.
Diese Abfolge wird mit Methode extrahieren von Visual Studio 2012 übernommen. Dazu markieren Sie die Codezeilen, die in eine eigene Methode überführt werden sollen, im Menü Umgestalten • Methode extrahieren oder über das Kontextmenü des markierten Codes. Die neue Methode wird mit dem ausgewählten Code erstellt, und der im vorhandenen Member ausgewählte Code wird durch einen Aufruf der neuen Methode ersetzt.
Als anschauliches Beispiel soll uns die folgende Methodendefinition dienen:
public static double TestProc() {
int intVar;
intVar = 10;
double result = Math.Pow(2, intVar);
Console.WriteLine("Das Ergebnis lautet: {0}", result);
return result;
}
In Abbildung 17.18 ist das Szenario des Auslagerns von Code zu erkennen. Zu Demonstrationszwecken ist hier bis auf die Deklaration der lokalen Variablen intVar der gesamte Code markiert. Der Dialog öffnet sich, sobald Sie der Entwicklungsumgebung mitgeteilt haben, dass Sie die markierten Codezeilen extrahieren wollen. Tragen Sie hier nur noch einen passenden Bezeichner für die neue Methode ein. Eine Vorschau zeigt die Signatur der Methode. Der Rest wird von Visual Studio erledigt.
Das Ergebnis ist wie folgt:
public static double TestProc() {
int intVar;
return NewMethod(out intVar);
}
private static double NewMethod(out int intVar) {
intVar = 10;
double result = Math.Pow(2, intVar);
Console.WriteLine("Das Ergebnis lautet: {0}", result);
return result;
}
Abbildung 17.18 In diesem Dialog geben Sie den Namen der neuen Methode ein.
Die ausgeschnittenen Codezeilen werden durch den Aufruf der neuen Methode ersetzt. Ich habe mit Absicht die Anweisung zur Deklaration der lokalen Variablen nicht mit extrahiert. Wie sehr schön zu erkennen ist, berücksichtigt der Umgestaltungsprozess, dass intVar in der neuen Methode gesetzt und zur Berechnung einer Potenzzahl ausgewertet wird. Da intVar nur deklariert, jedoch nicht initialisiert ist, erwartet die extrahierte Methode einen out-Parameter. Wäre die Initialisierung vor dem Aufruf der extrahierten Methode erfolgt, wäre der Parameter ohne out erzeugt worden.
17.7.2 Bezeichner umbenennen
Der erste Schritt zu einem verständlichen und gut interpretierbaren Code ist eine Namensgebung, die bereits Rückschlüsse auf den Einsatzzweck des betreffenden Mitglieds zulässt. Eine Methode namens CreateDatabase verrät bereits sehr viel, TestProc hingegen gar nichts.
Am Ende eines Projekts, wenn man den geschriebenen Code noch einmal durchsieht, fallen oft Bezeichner ins Auge, die möglicherweise besser hätten gewählt werden können. Früher hätten Sie wahrscheinlich darauf verzichtet, den unpassenden Bezeichner durch einen besser beschreibenden zu ersetzen, denn im Anschluss daran hätten Sie den gesamten Code durchforsten müssen, um ihn an allen Stellen auszutauschen. Abgesehen davon, dass sich dabei Fehler durch Versäumnisse einschleichen können, kann die dafür benötigte Zeit anders investiert werden.
Auch für diese Fälle bietet das Refactoring durch Umbenennung eine Lösung. Umbenannt werden können Felder, Eigenschaften, lokale Variablen, Methoden, Namespaces und Typdefinitionen. Der Umbenennungsprozess erfasst dabei nicht nur Deklarationen und Aufrufe, er kann auch auf Kommentare und in Zeichenfolgen angewandt werden. Er ist zudem intelligent genug, alle Vorkommen des Elements zu erfassen.
Positionieren Sie den Cursor in dem betreffenden Bezeichner, und klicken Sie im Menü Umgestalten auf Umbenennen. Es öffnet sich ein Fenster, in dem Sie den neuen Namen eintragen. Zudem legen Sie hier auch fest, ob ebenfalls in Kommentaren und Zeichenfolgen nach dem alten Bezeichner gesucht werden soll.
Vorausgewählt ist im Dialog die Option Vorschau der Verweisänderungen. Dahinter verbirgt sich ein Fenster, in dem alle Änderungen im Projekt farblich gekennzeichnet sind. Sie können im oberen Teil des Fensters die Änderungsvorschläge annehmen oder auch verwerfen. Das kann unter Umständen erforderlich sein, wenn Sie innerhalb des Codes zwei gleichnamige Bezeichner für verschiedene Elemente verwenden.
Visual Studio unterstützt die Umbenennung über die Projektgrenzen hinweg. Wenn Sie beispielsweise eine Konsolenanwendung entwickeln, die auf eine Klassenbibliothek verweist, werden beim Umbenennen eines Typs in der Klassenbibliothek auch die Verweise auf den Typ der Klassenbibliothek in der Konsolenanwendung aktualisiert.
17.7.3 Felder einkapseln
Nach den Paradigmen der Objektorientierung sollten alle Felder gekapselt werden. .NET-Anwendungen lösen das mit Hilfe von Eigenschaften, die einen get- und einen set-Accessor haben. Nicht immer werden Sie sich an die objektorientierten Grundsätze halten, Sie müssen es auch nicht. Daher kann es vorkommen, dass Sie eine Variable als public definiert haben, aber zu einem späteren Zeitpunkt feststellen, dass die Kapselung in einer Eigenschaft unbedingt erforderlich ist. Über das Menü Umgestalten • Feld kapseln ist das sehr schnell möglich, wenn Sie den Cursor vorher in die Codezeile des betreffenden Feldes gesetzt haben. Weil mit der Kapselung möglicherweise auch eine Änderung des Aufrufs verbunden ist, werden im Code auch die Anweisungen herausgefiltert, die von der Änderung betroffen sind.
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.