Refactoring Patterns #2 Extract Method

Refactoring Patterns #2 - Extract Method

Mit dem Extract Method Pattern kann eine Methoden in einer Klasse verkürzt werden. Hierbei wird ein Teil des Codes in eine neue Methode ausgelagert.
 

Als Beispiel dafür dient die Klasse "UserRegistrationService". In der Methode "registerUser" wird zunächst geprüft, ob der gleiche Benutzer bereits existiert, ob das Passwort1 und Passwort2 identisch ist und ob das Passwort lang genug ist. In einer realen Implementierung gibt es bestimmt noch weitere checks und würde man statt mysqli vielleicht auch ein Framework verweden.


Der gezeigt PHP-Code dienst also nur zur Demonstation:

ERROR: Content Element with uid "2070" and type "beautyofcode_contentrenderer" has no rendering definition!

Die Implementierung der Methode "saveRegistration" hat über 30 Zeilen. Es ist schwer zu verstehen was darin passiert und es passieren mehrere Dinge hintereinander.

     

    Code mit dem Extract Method Pattern in eigene Methoden auslagern

    Mit dem "Extract Method"-Pattern können Teile in einer Methode ausgelagert werden, die von anderen Teilen unabhängig sind. Ein erster Schritt könnte also sein, den Teil auszulagern, der prüft, ob es schon einen Benutzer gibt. Ein bisschen tricky ist dabei, dass die Datenbankverbindung auch später genutzt wird, um den Benutzer zu speichern. Aus diesem Grund extrahieren wird gleich zwei Methoden:

    1. connectToDatabase()
    2. getUserExists($username)

    ERROR: Content Element with uid "2073" and type "beautyofcode_contentrenderer" has no rendering definition!

    Die Implementierung der Methode "saveRegistration" ist nun schon deutlich kürzer. Aber nach dem ersten Refaktoring können weitere folgen. Der Code in der Methode enthält nun im wesentlichen noch zwei Teile.

    1. Validierung der Eingabedaten (Existiert der Benutzer und stimmen Passwortlänge, ...) => Zeile 48-59
    2. Speichern der Daten, wenn alles korrekt ist. => Zeile 61 - 70

    Diese beiden Teile lassen sich nun ebenfalls in eigene Methoden extrahieren:

    1. validateUser($username, $password1, $password2)
    2. storeUser($username, $password)

     

    ERROR: Content Element with uid "2075" and type "beautyofcode_contentrenderer" has no rendering definition!

    Woran Code für Extract Method erkennen

    Klassischerweise kann man in langen Methoden nach Stellen suchen, die auf den selben Variaben arbeiten. Möglicherweise wird nur mit dem Ergebnis einer Variable im Code weitergearbeitet? Wenn das der Fall ist, sind solche Blöcke ein Kandidat für "Extract Method".

    Fazit

    Der Code der Klasse ist ingesamt länger geworden, aber dafür ist die Logik in den einzelnen Methoden besser zu verstehen und gekapselt. Die längste Methode hat gerade 10 Zeilen.

    Durch die Anwendung des "Extract Method"-Patterns ergeben sich ggf. weitere Möglichkeiten. Zum Beispiel kann man erkennen, dass manche Methoden nur Datenbankspezifisch sind (z.b. connectToDatabase, getUserExists, oder storeUser). In einem weiteren Schritt könnten diese Methoden mit dem "Extract Class"-Pattern in eine eigene Klasse extrahiert werden.
     

    Navigation