Das DRY-Prinzip: Das schwierige Gleichgewicht zwischen Wiederverwendbarkeit und Klarheit des Codes finden

Dieser Artikel befasst sich mit dem DRY-Prinzip (Don't Repeat Yourself) und seinen Auswirkungen auf die Codequalität. Er unterstreicht seine Bedeutung für die Vermeidung von Wiederholungen und die Erleichterung der Wartung, weist aber auch auf die Risiken einer übermäßigen Anwendung dieses Prinzips hin, die der Klarheit und der Projektentwicklung abträglich sein kann. Ziel ist es, das richtige Gleichgewicht zwischen Wiederverwendung und Einfachheit zu finden.
In diesem Artikel untersuchen wir das DRY-Prinzip (Don't Repeat Yourself) und seine Auswirkungen auf die Codequalität. Obwohl es zur Vermeidung von Redundanzen und zur Erleichterung der Wartung unerlässlich ist, kann seine übermäßige Anwendung manchmal das Verständnis und die Entwicklung eines Projekts erschweren. Lassen Sie uns herausfinden, wie wir das richtige Gleichgewicht zwischen Wiederverwendung und Klarheit finden können.
Das DRY-Prinzip: ein zweischneidiges Schwert.
Vor kurzem haben wir der ursprünglichen Version unseres aktuellen Projekts, das bald in Produktion gehen wird, den letzten Schliff gegeben. Da sich die Komplexität unseres Codes aufgrund der Natur des Projekts weiterentwickelt, legen wir großen Wert darauf, ihn einfacher und schlanker zu gestalten. Durch die Anwendung von Best Practices wie dem DRY-Prinzip (Don't Repeat Yourself) zur Vermeidung von Redundanzen streben wir eine hohe Qualität an.
Dies führt mich zu einer Diskussion über ein Prinzip, das ich für ein zweischneidiges Schwert halte, das man klug anwenden und gleichzeitig pragmatisch bleiben sollte.
Warum sollte man das DRY-Prinzip anwenden?
Das DRY-Prinzip „Don't Repeat Yourself“, ist eine Philosophie der Softwareentwicklung, die darauf abzielt, die Redundanz im Quellcode zu minimieren. Obwohl dieser Ansatz weithin für seine Effektivität bei der Bewältigung der Komplexität des Codes gelobt wird, ist es entscheidend zu verstehen, wie seine starre Anwendung manchmal zu Verwirrung führen kann.
Das Hauptziel von DRY ist es, die Wiederverwendung von Code zu fördern, wodurch potenzielle Fehler reduziert und die Wartung verbessert werden. Indem Entwickler die Duplizierung von Codeteilen vermeiden, können sie die Geschäftslogik zentralisieren und so Aktualisierungen und Korrekturen erleichtern.
Beispiel:
Nehmen wir einen Fall, in dem wir zwei Entitäten in einer Symfony-Anwendung haben: User
und Admin
. Diese beiden Einheiten haben gemeinsame Eigenschaften, als firstname
, lastname
, und email
. Ohne Normalisierung würden wir diese Eigenschaften jedoch in jeder Entität duplizieren, was gegen das DRY-Prinzip verstößt. Hier ein Beispiel, wie es ohne Normalisierung aussehen würde :
// src/Entity/User.php
namespace App\Entity;
class User
{
private string $firstname;
private string $lastname;
private string $email;
private string $job;
}
// src/Entity/Admin.php
namespace App\Entity;
class Admin
{
private string $firstname;
private string $lastname;
private string $email;
private array $roles;
}
In diesem Fall würde der Inspektor von PhpStorm oder PHP Mess Detector eine Duplizierung der Eigenschaften melden firstname
, lastname
, und email
in beiden Entitäten. Ein klassischer Vorschlag wäre, die Vererbung zu nutzen, um diese Eigenschaften in einer übergeordneten Klasse zu zentralisieren, Account
, um die Duplikation zu eliminieren :
//src/Entity/Account.php
namespace App\Entity;
abstract class Account
{
private string $firstname;
private string $lastname;
private string $email;
}
Dann vererben wir User
und Admin
dieser Klasse Account
, und fügt gleichzeitig die spezifischen Eigenschaften jeder dieser Entitäten hinzu:
//src/Entity/User.php
namespace App\Entity;
class User extends Account
{
private string $job;
}
//src/Entity/Admin.php
namespace App\Entity;
class Admin extends Account
{
private array $roles;
}
Dieser Ansatz zentralisiert die gemeinsam genutzten Eigenschaften in einer Basisklasse. Er verbessert die Lesbarkeit und verringert die Fehleranfälligkeit durch Duplizierung. Es ist jedoch wichtig, daran zu denken, dass diese Lösung nicht immer mit einer ORM-Integration wie Doctrine gekoppelt werden muss. Manchmal ist es besser, direkt mit einem reinen Objektmodell zu arbeiten, um den Code unabhängig von einem Framework zu halten. Wenn die Verwendung von Doctrine später notwendig wird, können Sie diese Modelle immer noch mit Tools abbilden wie MappedSuperclass
oder SingleTableInheritance
.
Wenn die Abstraktion übermäßig wird
Dieses Streben nach weniger Redundanz kann jedoch manchmal zu übermäßiger Abstraktion führen. Wenn Entwickler zu schnell nach Verallgemeinerungen streben, wird der Code für diejenigen, die mit den spezifischen Details des Projekts nicht vertraut sind, schwerer verständlich. Komplexe Abstraktionen können Schichten von Indirektionen schaffen, die den Code nicht klarer machen, sondern zusätzliche Ebenen der Verwirrung einführen.
Ein weiterer Aspekt, den es zu berücksichtigen gilt, ist, dass die strikte Befolgung des DRY-Prinzips zu generischen Codestrukturen führen kann, die für den jeweiligen Einzelfall nicht optimal sind. Wenn man beispielsweise eine Eigenschaft wie eine eindeutige Kennung (ID) für verschiedene Entitäten faktorisiert, kann man feststellen, dass die zugehörigen Regeln je nach Geschäftskontext variieren. Nehmen wir den Fall eines Systems, in dem die Nutzer haben einfache numerische IDs, während die Klienten erfordern IDs mit einem regionalen Präfix (z. B, EU-12345
). In diesem Fall kann der Versuch, die Verwaltung der IDs zu zentralisieren, den Code mit zusätzlichen Bedingungen komplexer machen. Manchmal kann die absichtliche Duplizierung von Teilen des Codes, die auf die jeweilige Entität zugeschnitten ist, die Lesbarkeit und Wartbarkeit verbessern, vor allem wenn in Zukunft mit spezifischen Variationen zu rechnen ist.
DRY im Kontext moderner Architekturen
In modernen Architekturen, insbesondere bei Microservices und Polyrepo-Strategien, wird manchmal dazu geraten, zwischen isolierten Diensten zu kopieren und einzufügen. Da jeder Dienst eigenständig und unabhängig ist, kann eine moderate Duplizierung von Code zwischen den einzelnen Diensten eine bessere Verwaltung lokaler Änderungen ermöglichen und die Bereitstellung erleichtern, ohne andere Teile des Systems zu beeinträchtigen.
Das richtige Gleichgewicht zwischen der Wiederverwendung von Code und der Übersichtlichkeit zu finden, ist eine ständige Herausforderung für die Entwickler. Es ist wichtig zu erkennen, dass DRY eine Richtlinie und keine absolute Regel ist. Möglicherweise müssen Kompromisse eingegangen werden, um den Code lesbar und verständlich zu halten und gleichzeitig die Vorteile der Wiederverwendung zu nutzen.
Schlussfolgerung
Zusammenfassend lässt sich sagen, dass das DRY-Prinzip zwar ein wertvoller Leitfaden zur Verbesserung der Codequalität ist, seine starre Anwendung jedoch manchmal zu Verwirrungen führen kann. Im Zusammenhang mit komplexen Architekturen wie Microservices können Entwickler sogar dazu angehalten werden, Code zu duplizieren, um die Unabhängigkeit der Dienste zu gewährleisten. Wichtig ist, sich des Projektkontexts bewusst zu bleiben und ein optimales Gleichgewicht zwischen Wiederverwendung, Lesbarkeit und Pflege des Codes zu finden.