Refactoring

André Minhorst, Duisburg

Refactoring ist eines der Schlagwörter des Extreme Programming und untrennbar mit dem Unit-Testing und der testgetriebenen Entwicklung verbunden. Durch Refactoring verbessern Sie die Struktur und Lesbarkeit des Codes einer Anwendung unter Beibehaltung der Funktionalität und erleichtern damit änderungen und Erweiterungen der Funktion der Anwendung.

Refactoring ist eine Tätigkeit, die Chefs und Managern vermutlich nicht gefallen wird, weil sie erstmal keinen Gewinn bringt und ein Projekt nicht sichtbar vorantreibt – immerhin bezeichnet man Refactoring ausdrücklich als Vorgehensweise, die sich nicht auf die Funktion einer Anwendung auswirkt. Genau genommen kann man es als Aufräumen bezeichnen – man sortiert hier ein wenig aus, stellt dort ein wenig um und wirft vielleicht sogar ein paar Dinge weg. Die Analogie zum wirklichen Leben hinkt nur insofern, als dass Sie nicht Platz für etwas Neues, sondern die Voraussetzungen für dessen einfache Integration schaffen.

Refactoring optimiert noch nicht einmal die Performance – im Gegenteil: Viele Refactoring-Maßnahmen führen zu einer Verlangsamung der betroffenen Teile um wenige Prozentpunkte.

Aber – und das ist das Wichtigste – Sie bereiten den Quellcode durch Refactoring auf die Anwendung von Performance-Optimierungen vor, weil Sie diesen wesentlich besser lesbar machen und damit das Erkennen und Beseitigen von Performance-Bremsen erleichtern.

Die wichtigsten Ziele des Refactoring sind folgende:

  • Der Code soll für Menschen besser lesbar gemacht werden.
  • Die Struktur (Architektur) des Codes soll verbessert werden.
  • Der Code soll keine redundanten Abschnitte enthalten.
  • Der Code soll von Fehlern befreit und das Auffinden von Fehlern erleichtert werden.
  • Die Anwendung soll robuster werden.
  • Refactoring besteht aus einem oder mehreren Refactoring-Maßnahmen – je nachdem, wie gute Vorarbeit man geleistet hat und wie viel Verbesserungspozential der Code noch bietet. Mit diesen Maßnahmen können Sie den Code Stück für Stück besser strukturieren und lesbarer machen.

    Refactoring ist in Zusammenhang mit objektorientierten Programmiersprachen entstanden. Da VBA nicht alle Aspekte der Objektorientiertheit beinhaltet, lassen sich längst nicht alle in Literatur und Internet beschriebenen Refactoring-Maßnahmen auf VBA-Code anwenden.

    In den nachfolgenden Kapiteln lernen Sie ausschließlich solche Refactorings kennen, die für mit VBA entwickelte Anwendungen geeignet sind. Zu jedem Refactoring finden Sie ein Beispiel und – soweit sinnvoll – eine Abbildung zur Veranschaulichung der Vorgehensweise.

    In manchen Fällen stellen wir auch Refactorings vor, die in der Literatur nicht beschrieben sind – beispielsweise die Umwandlung einer Funktion mit mehreren Rückgabeparametern in eine Klasse mit entsprechenden Eigenschaften.

    Unbewusst werden Sie vielleicht schon das eine oder andere Refactoring an Ihrem Code vorgenommen haben, weil es Ihnen einfach sinnvoll erschien. Ein gutes Beispiel dafür ist das Extrahieren einer Methode, bei dem man eine oder mehrere Zeilen Code, die an mehreren Stellen in einer oder mehreren Prozeduren vorkommen, in eine neue Prozedur ausgliedert.

    Hinweis

    Im Internet gibt es eine Menge Informationen zum Thema Refactoring, meist in Verbindung mit objektorientierten Sprachen wie Java oder VB.NET. Wenn Sie im Internet nach zusätzlichem Informationsmaterial suchen, sollten Sie als Suchbegriff zusätzlich noch den Namen Martin Fowler eingeben. Die in diesem Beitrag und den geplanten Fortsetzungen vorgestellten Refactoring-Maßnahmen lehnen sich an die auf der folgenden Internetseite aufgeführten Informationen an und sind den speziellen Gegebenheiten unter Microsoft Access beziehungsweise VBA angepasst: http://www.refactoring.com/catalog/index.html

    Refactoring sollte unter zwei Voraussetzungen erfolgen:

  • Der zu refaktorierende Code ist – soweit wie unter VBA möglich – objektorientiert.
  • Es gibt automatisierte Tests für den zu ändernden Code, mit dem man den Code vor und nach einer Refactoring-Maßnahme testen kann.
  • Objektorientierung

    Die erste Voraussetzung ist nirgends festgelegt, weil Refactoring ohnehin aus der objektorientierten Programmierung stammt und dort zusammenhängende Methoden und Eigenschaften in Klassenmodulen untergebracht sind. Standardmodule wie in VBA werden dort nicht verwendet. Viele Refactoring-Maßnahmen beziehen sich ausdrücklich auf Klassen. Es gibt zwar einige, die auf Eigenschafts- oder Methodenebene anwendbar und damit auch für VBA-Prozeduren in Standardmodulen geeignet sind, aber die Kapselung von Funktionalität in Klassen kommt dem Refactoring-Prozess in den meisten Fällen entgegen.

    Tests

    Die zweite Voraussetzung ist die Absicherung der vom Refactoring betroffenen Funktionalität. Und hier kommen die weiter oben erwähnten Unit-Tests und die testgetriebene Entwicklung ins Spiel: Wenn Sie die Anforderungen an die Eigenschaften und Methoden durch das vorherige Schreiben von Tests festlegen und auch überprüfen, können Sie auch ohne Sorge änderungen in Form von Refactoring-Maßnahmen durchführen. Dazu stellen Sie einfach sicher, dass die Anwendung vor dem Refactoring funktioniert, führen die änderungen durch und testen anschließend, ob weiterhin alles reibungslos läuft. Dazu können Sie die Tests verwenden, mit denen Sie auch die entsprechenden Methoden entwickelt haben – der einzige Unterschied ist, dass die Tests in diesem Zusammenhang „Regressionstests“ genannt werden.

    Testen Sie so oft wie möglich – je kleiner die änderungen zwischen zwei Tests sind, umso schneller finden Sie eventuell auftretende Fehler.

    Hinweis

    Weitere Informationen über die testgetriebene Entwicklung finden Sie im Beitrag Testgetriebene Entwicklung mit Access in Ausgabe 4/2004 von Access im Unternehmen.

    In den folgenden Abschnitten geht es los: Sie lernen die ersten Refactoring-Maßnahmen kennen. In diesem Beitrag stellen wir Ihnen gängige Maßnahmen für das Refactoring von Variablen und Methoden vor.

    Variablen bieten gute Ansatzpunkte für Refactoring. Nachfolgend finden Sie einige Refactoring-Maßnahmen, die je nach Situation Variablen hinzufügen, entfernen oder einfach ändern.

    Public Sub EinsBisZehn()
        Dim i As Integer
        For i = 1 To 10
            Debug.Print i
        Next i
    End Sub

    Quellcode 1

    Private Sub KombinationsfeldFuellen(intErstesJahr As Integer, intLetztesJahr As Integer)
        Dim i As Integer
        Dim strJahre As String
        For i = intErstesJahr To intLetztesJahr
            strJahre = strJahre & i & ";"
        Next i
        strJahre = Mid(strJahre, 1, Len(strJahre) - 1)
        Me.cboJahreszahlen.RowSource = strJahre
    End Sub

    Quellcode 2

    Public Sub Rechteck(a As Integer, b As Integer)
        Dim temp As Integer
        temp = a * b
        Debug.Print "Fläche: " & temp
        temp = 2 * (a + b)
        Debug.Print "Umfang: " & temp
    End Sub

    Quellcode 3

    Hinweis

    In den Schritt-für-Schritt-Anweisungen der einzelnen Refactoring-Maßnahmen finden Sie oft den Hinweis, die Anwendung zu kompilieren. Damit sollen meist bei der änderung von Variablen vergessene Vorkommen der jeweiligen Variablen gefunden werden. Damit der Debugger sich meldet, wenn eine nicht deklarierte Variable im Quellcode enthalten ist, müssen Sie zu Beginn des Moduls die Zeile Option Explicit einfügen. Es dürfen dann keine Variablen mehr ohne Deklaration verwendet werden.

    Temporäre Variable zerlegen

    Es gibt mehrere Möglichkeiten, temporäre Variablen mehrfach zu verwenden. Die erste Möglichkeit ist die Verwendung in einer Schleife, was vollkommen legitim und außerdem unausweichlich ist, wie das Beispiel aus Quellcode 1 zeigt.

    Die zweite Möglichkeit ist gegeben, wenn der Inhalt der Variablen sukzessiv erweitert wird, etwa um den Inhalt eines Kombinationsfeldes zu erzeugen (im Fall des Beispiels aus Quellcode 2 handelt es sich um Jahreszahlen).

    Die dritte Möglichkeit besteht in der Verwendung einer Variablen für verschiedene Zwecke, wie in dem Beispiel aus Quellcode 3.

    Die Methode speichert nacheinander zwei völlig unterschiedliche Informationen in einer Variablen.

    Im vorliegenden Fall ist das noch überschaubar, aber wenn Sie sich noch 30 Zeilen Code zwischen den beiden Verwendungen der Variablen temp vorstellen, nimmt die übersichtlichkeit rasch ab.

    Beschreibung der Vorgehensweise

    Verwenden Sie jede Variable nur einmal und vergeben Sie außerdem sprechende Namen für jede Variable. Damit erhöhen Sie die übersichtlichkeit und können außerdem später auf alle temporären Variablen zugreifen, ohne deren Werte erneut ermitteln zu müssen. Gehen Sie folgendermaßen vor:

  • Benennen Sie die temporäre Variable in der Deklaration nach dem Zweck des ersten Vorkommens.
  • ändern Sie den Variablennamen an allen Stellen im Code, die sich auf die erste temporäre Variable beziehen.
  • Public Function AnzahlPersonen()
        AnzahlPersonen = DCount("[Kunden-Code]", "Kunden") _        + DCount("[Personal-Nr]", "Personal")
    End Function

    Quellcode 4

    Public Function AnzahlPersonen()
        Dim intAnzahlKunden As Integer
        Dim intAnzahlMitarbeiter As Integer
        intAnzahlKunden = DCount("[Kunden-Code]", "Kunden")
        intAnzahlMitarbeiter = DCount("[Personal-Nr]", "Personal")
        AnzahlPersonen = intAnzahlKunden + intAnzahlMitarbeiter
    End Function

    Quellcode 5

  • Deklarieren Sie eine neue Variable mit einem Namen, der sich nach dem Zweck des zweiten Auftretens dieser Variablen richtet.
  • Passen Sie den Namen der Variablen im Code an.
  • Verfahren Sie genauso für alle weiteren Vorkommen.
  • Kompilieren Sie um sicherzugehen, dass Sie die ursprüngliche Variable an allen Stellen im Code ersetzt haben. (
  • Die Beispielprozedur aus Quellcode 3 sieht nach dieser Behandlung wie folgt aus (änderungen fett gedruckt):

    Public Sub Rechteck(a As Integer, b As Integer)
        Dim intFlaeche As Integer
        Dim intUmfang As Integer
        intFlaeche = a * b
        Debug.Print "Fläche: " & intFlaeche
        intUmfang = 2 * (a + b)
        Debug.Print "Umfang: " & intUmfang
    End Sub 

    Erklärende Variable einführen

    Man verwendet oft komplizierte und aus mehreren Teilen bestehende Ausdrücke in Methoden, deren Ergebnis nicht unbedingt offensichtlich ist.

    Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
    Hier geht es zur Bestellung des Jahresabonnements des Magazins Access im Unternehmen:
    Zur Bestellung ...
    Danach greifen Sie sofort auf alle rund 1.000 Artikel unseres Angebots zu - auch auf diesen hier!
    Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

    Schreibe einen Kommentar