“We build our computer (systems) the way we build our cities: over time, without a plan, on top of ruins.”
Ellen Ullman
Neue Teams und neue Kollegen, das bedeutet häufig auch neue, von den Kollegen verwendete Bibliotheken. Häufig ist es der ganz persönliche Geschmack, der die Wahl auf eine spezielle Bibliothek fallen lässt.
Einige neue Kollegen schwören nun aus AssertJ für ihre JUnit Test. Also sofort wieder eine neue Bibliothek in den eigenen Werkzeugkasten aufnehmen?
Während ich noch mit JUnit 4 arbeitete, nutzte ich gerne Hamcrest um gut lesbare Assertions zu formulieren. Seitdem ich JUnit 5 verwende, nutze ich hingegen kaum noch externe Assertions.
Dies hat einerseits damit zu tun, dass JUnit 5 diverse Ergänzung bereitstellt, die früheren Versionen fehlten. Andererseits formuliere ich für ein Feature mittlerweile viel mehr Test und diese sehr viel kleiner und spezieller. Das Überprüfen komplexeren Datenstrukturen ist daher kaum noch nötig und kann mit JUnit 5 Bordmitteln erfolgen.
Keine zusätzlichen Bibliotheken oder Frameworks zu verwenden, beim Testen etwa Hamcrest, AspectJ, Truth oder in der Entwicklung Guava oder Apache Commons, oder ihren Einsatz auf das Notwendigste zu reduzieren, ist eine Form von Minimalismus.
Dieser Minimalismus ist natürlich kein Selbstzweck, sondern reduziert die Komplexität der Anwendung und vereinfacht Wartung und Weiterentwicklung.
Jede zusätzliche Bibliothek bedeutet, zusätzliche Arbeit zum Verständnis der Verwendung dieser Bibliothek. Nicht nur für den Entwickler, der diese Bibliothek initial ins Projekt einführt, sondern für jeden anderen Entwickler, der später auf der Code Basis arbeiten muss.
Bibliotheken werden häufig aus der Idee geboren, ein bekanntes Problem auf eine ganz neue Art und Weise anzugehen. Daher sind Bibliotheken in vielen Fällen nicht eine neue Sammlung von Klassen und Methoden, sondern verlangen vom Entwickler eine neue Herangehensweise. Viele Bibliotheken bedeuten also nicht viele Werkzeuge zu beherrschen, sondern viele Philosophien zu verstehen.
Außerdem hängen Bibliotheken nicht im luftleeren Raum. Moderne Anwendungen enthalten oft hunderte von direkten oder indirekten Abhängigkeiten, die ihrerseits untereinander Abhängigkeiten auf unterschiedliche Versionsstände haben. Manche Bibliotheken können nur in unerwünschten Versionen genutzt werden, weil es sonst zu Inkompatibilitäten mit anderen Bibliotheken führt.
Viele Bibliotheken lösen außerdem die gleichen Probleme in unterschiedlicher Form, so dass verschiedene Entwickler gleiche Anforderungen im selben Projekt mit unterschiedlichen Bibliotheken lösen. Viele verschiedene Bibliotheken bedeuten auch, dass die Entwickler diese Bibliotheken auch beherrschen müssen oder Cargo Cult Programming in Kauf genommen wird.
Oft wird auch auf Funktionen aus Bibliotheken verharrt, auch wenn die Funktionalität mittlerweile Bestandteil der Java Standard Bibliothek geworden. Häufig sogar noch viel eleganter als in der alten Bibliothek. Häufig weil keine Zeit vorhanden ist, die Code Basis adäquat zu pflegen oder aus Unsicherheit, weil eben diese Bibliothek nicht beherrscht wird.
Gerade in Legacy Code, der über Jahre gewachsen ist, findet sich die Handschrift dutzender Entwickler, hunderte Bibliotheken haben sich angesammelt, um manchmal nur eine einzige Methode bereitzustellen. In manchen Klassen werden immer und immer wieder Variablen auf null
getestet, weil obskure Hilfsbibliotheken verwendet werden. Stattdessen wäre der Einsatz des Null-Patterns, Guard-Decorator oder Guard-Clauses hilfreich.
Bibliotheken sind eines der wichtigsten Hilfsmittel um schnell hochwertigen Code zu entwickeln. Aber bevor wir eine neue Bibliothek einsetzen oder eine alte weiterverwenden, sollten wir uns fragen, ob wir sie wirklich benötigen!