In der Welt der Softwareentwicklung gilt die Maxime „Don’t Repeat Yourself“ (DRY) seit langem als unantastbare Programmierweisheit. Von Anfang an lernen Entwickler, dass Duplikate im Code als Fehler zu betrachten und daher unbedingt zu vermeiden sind. Die Idee dahinter ist einleuchtend: Wer Code wiederverwendet statt ihn zu duplizieren, erhöht die Wartbarkeit, vermeidet Inkonsistenzen und spart Zeit. Doch in der Praxis sieht die Realität oft anders aus. Manchmal ist Duplikation nicht nur unvermeidlich, sondern sogar die bessere Lösung.
Warum das so ist, erklärt sich daraus, wie Abstraktionen entstehen, sich entwickeln und manchmal scheitern können.Die Versuchung, sofort zu abstrahieren, sobald sich ähnliche Codeblöcke zeigen, ist groß. Schließlich scheint es auf den ersten Blick logisch, gleiche Logik in einer gemeinsamen Funktion oder Klasse zu bündeln. In einem idealisierten Szenario führt das zu klarerem, kompakterem Code, der leichter erweiterbar ist. Doch der entscheidende Punkt ist, dass diese Logik in der Realität selten statisch bleibt.
Anforderungen verändern sich ständig, oft unvorhersehbar und nicht synchron. So kann aus einer anfänglich simplen Funktion schnell eine komplexe Struktur mit zahlreichen Parametern und Verzweigungen werden, die kaum jemand versteht oder ohne Risiko verändern kann.Ein anschauliches Beispiel ist die Berechnung von Bonuszahlungen für unterschiedliche Arbeitnehmergruppen wie. Mitarbeiter und Auftragnehmer. Anfangs teilen beide möglicherweise eine einfache Berechnungsgrundlage – eine Basisprämie multipliziert mit einem Leistungsfaktor.
Die intuitive Reaktion lautet, diese Logik in eine gemeinsame Funktion auszulagern. Spätestens hier greifen die DRY-Prinzipien ein. Aber dann kommen neue Anforderungen hinzu. Ein Mitarbeiter erhält etwa einen zusätzlichen Bonus für die Betriebszugehörigkeit, der in der gemeinsamen Funktion als weiterer Parameter ergänzt wird. Später wird für Auftragnehmer eine andere Regel eingeführt, beispielsweise eine Bonusanpassung abhängig von der Anzahl der gearbeiteten Monate, was weitere Parameter und Bedingungen nötig macht.
Nach und nach wächst die Funktion zu einem unübersichtlichen Konstrukt mit vielen Sonderfällen, das zu warten und zu erweitern zunehmend schwieriger wird.Dieses Phänomen ist als „Tod durch tausend Parameter“ bekannt. Die ursprüngliche Idee einer simplen, wiederverwendbaren Funktion wird durch immer mehr Variationen überfrachtet. Änderungen aus dem einen Anwendungsfall bedrohen plötzlich die Funktionalität der anderen Fälle. Entwickler finden sich in einem Dilemma wieder: Entweder riskieren sie, durch eine Änderung anderen Code zu brechen, oder sie fügen noch mehr Bedingungen und Parameter hinzu, um alle Szenarien abzudecken.
So verkommt die vermeintlich gute Abstraktion letztlich zu einer Fehlerquelle und einem Hemmschuh für weitere Entwicklungen.Warum passiert das? Ein zentraler Punkt liegt darin, dass Entwickler oft versuchen, Abstraktionen zu schaffen, ohne das Problem wirklich zu verstehen. Frühzeitige Abstraktion basiert häufig auf oberflächlichen Ähnlichkeiten, die gar nicht zwingend eine gemeinsame Lösung rechtfertigen. In Wahrheit unterscheiden sich die Anforderungen oder das Verhalten in diesen Fällen oft fundamental. Wenn dann versucht wird, eine vermeintliche Gemeinsamkeit abzubilden, entsteht zwangsläufig ein Kompromiss, der kaum eine der Varianten wirklich gut abdeckt.
Die wesentlich bessere Herangehensweise besteht darin, sich Zeit zu nehmen und abstrahieren erst dann zu versuchen, wenn das Muster klar erkennbar ist – das heißt, wenn mehrere ähnliche Implementierungen vorliegen und deutlich wird, welche Gemeinsamkeiten wirklich bestehen und welche Unterschiede essenziell sind. So kann die Abstraktion gezielt und fokussiert gestaltet werden, wodurch die Gefahr einer überfrachteten, schwer wartbaren Funktion minimiert wird. Dabei hilft es auch, Duplikation als eine ehrliche und sichtbare Form der Programmierung zu begreifen. Sie zeigt die unterschiedlichen Anforderungen offen auf und erlaubt es, Änderungen lokal vorzunehmen, ohne andere Bereiche zu beeinflussen.Einige Programmierparadigmen und -prinzipien unterstreichen diesen Ansatz.
Sandi Metz etwa formuliert treffend: „Duplication is far cheaper than the wrong abstraction.“ Das bedeutet, dass die Kosten und die Komplexität, die eine falsche oder verfrühte Abstraktion mit sich bringt, deutlich höher sind als die Nachteile von akzeptierter Duplikation. Wenn man sich die Zeit nimmt, die Bedürfnisse und Variationen im Code genau zu verstehen, lässt sich später eine robustere und sinnvollere Abstraktion erstellen, die weniger komplex und besser wartbar ist.Natürlich bedeutet das nicht, dass jede Form von Duplikation automatisch akzeptabel ist. Utility-Funktionen, die sehr spezifische Aufgaben wie Parsen, Validierung oder Formatierung erledigen, sollten tatsächlich sofort abstrahiert werden.
Sie haben meist einen klar umrissenen Zweck und ändern sich selten, wodurch das Risiko verfrühter Abstraktionen hier deutlich geringer ist. Die Herausforderung liegt vor allem bei komplexeren Geschäftslogiken mit variierenden Anforderungen, bei denen es verführerisch scheint, sofort eine allgemeine Lösung anzustreben.Ein weiterer wichtiger Aspekt ist die Zusammenarbeit im Team. Oft ändern unterschiedliche Entwickler über längere Zeiträume eine gemeinsame Abstraktion ohne vollständiges Verständnis der bestehenden Komplexität und ohne umfassende Abstimmung. Dies führt zu weiteren Anpassungen und mehr Parametern, die vermeintlich kleinen Änderungen relativieren, aber die Abstraktion immer schwerer machbar und anfällig für Fehler machen.
Der schleichende Charakter dieser Entwicklung macht sie besonders gefährlich, denn das Aufbrechen einer alten, gut getarnten Codefalle kostet zunehmend Ressourcen und Zeit, die bei laufendem Betrieb meist knapp sind.Geduld und Achtsamkeit sind die Schlüssel, um den richtigen Moment zur Abstraktion zu finden. Statt beim ersten Anzeichen von Duplikation sofort eine gemeinsame Funktion zu schaffen, sollte man die Wiederholungen bewusst zulassen und beobachten, wie sich die Anforderungen entwickeln. So kann sich ein echtes Muster herausbilden, auf das eine sinnvolle Verallgemeinerung basieren kann. Dies ist eine Abkehr vom konventionellen DRY-Dogma, die langfristig jedoch zu stabileren, verständlicheren und leichter wartbaren Softwarelösungen führt.
Zusammenfassend lässt sich sagen, dass Duplikation nicht per se schlecht ist. Im Gegenteil: Sie zeigt dem Entwickler ehrlich, wo Ähnlichkeiten bestehen und wo Unterschiede elementar sind. Vorschnelle Abstraktion kann dabei mehr Probleme schaffen, als sie löst, weil sie aus mangelndem Verständnis der Problemstellung entsteht. Indem man Duplikation akzeptiert und gezielt auf Muster achtet, können im richtigen Moment nachhaltige und sinnvolle Abstraktionen geschaffen werden, die den Code tatsächlich verbessern. Wer sich von dem Dogma verabschiedet, jede Duplikation sofort zu eliminieren, schafft Raum für robustere und flexiblere Softwareentwicklung.
Das erfordert Mut zur Ungeduld, aber auf lange Sicht hilft diese Einstellung, die Qualität und Wartbarkeit des Codes erheblich zu steigern.