Seiten

Freitag, 7. August 2009

Beispiel für Refactoring von Beispiel für Closures

Vor ein paar Wochen hat mein Kollege Stefan Roock (Xing, Twitter) auf seinem Blog von einem "Beispiel für Closure" geschrieben. Wie so oft geht mir beim Lesen (fremden) Codes mein Das-ist-nicht-DRY-Alarm an. So auch bei Stefans Post. Es folgt ein Refactoring.

Stefan will die Laufzeit je Methode für eine Menge von Methoden messen. Die Menge hat er so bechrieben:

Ich konnte in seinem Post die Implementierung von tueA(), tueB() und tueC() nicht finden. Meine Annahme ist, dass sie ein wenig Laufzeit verbrauchen und etwas ausgeben:

Führt man nun die Menge an Methoden aus, so ist das die Ausgabe:

Stefan misst nun die Laufzeit der Methoden, und sein Output sieht (mit meiner Implementierung der Methoden) so aus:

Da ich ein Refactoring beabsichtige, darf sich das Verhalten des Codes, in diesem Falle der Output, nicht ändern.

Aber warum eigentlich Refaktorisieren? Mit Stefans Implementierung als solcher bin ich eigentlich zufrieden. Naja, da kann man noch ein Semikolon weglassen sowie eine Variable duration einführen und im GString hinterm println substituieren. Aber das ist Kleinkram, nebenbei machbar und hier kaum der Rede wert. Stefans Implementierung der Closure:

Nein, es geht mir um den Aufruf von Stefans Lösung (siehe Stefans komplette Lösung). Was muss ich tun, um die Laufzeit einer Menge von Methoden zu messen? Wo ist der Schalter, den ich einschalten muss? Stefan legt diesen Schalter um:

Seht Ihr die Redundanz? Stefan legt nicht einen Schalter um, sondern drei. Drei Mal muss er vor die Methoden timeLogged schreiben, inklusive geschweifte Klammer vor und nach der zu messenden Methode. Das ist nicht DRY.

DRY wäre es, eine Menge von Methoden einzeln zu messen. Das hier schwebt mir vor:

Und das geht. Die Closure-Magie, mit der das geht, hat Ted Naleid (Twitter, LinkedIn) in seinem Blogpost "Groovy closures make unit testing with “soft asserts” simple" ausführlich beschrieben. Hier ist meine Lösung:

Keep on DRYin', Stefan! "Bleib trocken, Stefan!" lag mir auf der Zunge, ging aber hier nun echt nicht... :-)

Links:

5 Kommentare:

  1. Ein weiteres Werkzeug, um Cross-Cutting-Concerns ohne AOP hinzubekommen. So kuul.

    AntwortenLöschen
  2. Hallo Bernd,
    kann leider dunkelblau auf schwarz schwer entziffern. Kannst Du mal die Farben ein bisschen heller machen?
    Danke!
    Matthias

    AntwortenLöschen
  3. @Matthias: Danke für den Hinweis. Habe die Farben angepasst. Ging ja wirklich gar nicht. Bin immer noch nicht zufrieden, mir fehlt aber momentan die Muße, meinen Ansprüchen gerecht zu werden. Geht's so zumindest zum entziffern?

    Was sagst Du zum Refactoring? :-)

    AntwortenLöschen
  4. @Johannes: Ging mir zwar mehr ums Refactoring, aber ja, bin bei Dir. Würde Groovy AOP vorziehen für Cross-Cutting-Concerns. Viel einfacher testbar.

    AntwortenLöschen
  5. Tja, Grovy ist schon stark! Du hast sehr schön gezeigt, wie man sich darin sehr kurz ausdrückt. Groovy erlaubt eben, sich die Sprache so zurechtzukonfigurieren, dass man seine Logik leicht ausdrücken kann. Das habe ich auch bei Splendicon wieder verifizieren können. (P.S.: Dein Text ist mit den neuen Farben jetzt gut lesbar!)

    AntwortenLöschen