Zweimal ist einmal zuviel


#1

In diesem Post möchte ich einmal ein Designprinzip beleuchten, das dem bekannten “don’t repeat yourself” ähnelt, aber damit nicht identlisch ist. Ich würde es “don’t say it twice” nennen (auch wenn das kein hübsches Akronym bildet). Es geht darum, das Ding, an dem man gerade werkelt, nicht öfter zu nennen als unbedingt nötig. Der Grund ist simpel: Man muss solche Referenzen immer synchron halten, wodurch sie anfällig für Copy-Paste-Fehler sind, nämlich wenn man nach dem Kopieren vergißt, eine dieser Referenzen zu ändern.

Es ist interessant, an wievielen verschiedenen Stellen einem dieses Problem begegnet. Ein paar Beispiele:

if und switch

Java Code:

[ol]
[li]String s;[/li]>
[li]if (x Integer.compare(p0.getAge(), p1.getAge()));. Hier wird zweimal das Feld age angesprochen. Besser wäre es, nur zu sagen “vergleiche Personen nach ihrem Alter”, und mit einer Helper-Methode der API geht das auch: Collections.sort(persons, Comparator.comparingInt(Person::getAge));.[/li]
instanceof

Dieses Beispiel ist etwas anders, da es sich diesmal auf eine Klasse bezieht:

Java Code:

[LIST=1]
[li][COLOR=#802B80]if(x instanceof String.class) {[/li]>
[li] String s = (String) x;[/li]>
[li] System.out.println(s.length());[/li]>
[li]}[/li]>
[/ol]

Aber wieder ist das Problem, dass wir den instanceof-Test und den Cast in der Schleife synchron halten müssen. Wieder kann ein Helper - diesmal ein eigener - Abhilfe schaffen:

Java Code:

[ol]
[li]public static ifInstanceOf(Object o, Class clazz, Consumer consumer) {[/li]>
[li] if(clazz.isInstance(o)) {[/li]>
[li] consumer.accept((T) o);[/li]>
[li] } [/li]>
[li]}[/li]>
[li] [/li]>
[li]ifInstanceOf(x, String.class, s -> System.out.println(s.length()));[/li]>
[/ol]

Hier sieht man auch sehr schön eine Stärke der Lambdas: Es lassen sich sehr gut Kontrollstrukturen und -flüsse abstrahieren. Früher war es schwierig, eine Schleife, z.B. einen Test oder einen Try-Block zu abstrahieren, weil es sehr umständlich war, das gewünschte individuelle Verhalten irgendwie hineinzubekommen. Jetzt kann diesen Part ein Lambda (in diesem Fall als Consumer) übernehmen.

Ich kann nur dazu ermutigen, genauer hinzuschauen, wenn einem eine Mehrfachnennung über den Weg läuft. Das lässt sich nicht immer vermeiden, aber in vielen Fällen bietet sich die Chance zum Abstrahieren.

Weiterlesen…