Single Responsibility Prinzip
Jede Klasse sollte genau eine Verantwortung haben. Wenn Sie eine Klasse mit und beschreiben müssen, verletzt sie wahrscheinlich dieses Prinzip. Änderungen sollten nur einen Grund haben, die Klasse zu modifizieren. Trennen Sie verschiedene Aufgaben in separate Klassen. Eine User-Klasse sollte User-Daten verwalten, nicht E-Mails versenden oder Datenbanken abfragen. Kleinere Klassen sind einfacher zu testen, zu verstehen und wiederzuverwenden.
Open-Closed Prinzip
Software sollte offen für Erweiterungen, aber geschlossen für Modifikationen sein. Nutzen Sie Abstraktion und Polymorphismus, um neues Verhalten hinzuzufügen ohne bestehenden Code zu ändern. Interfaces und abstrakte Klassen ermöglichen Erweiterbarkeit. Wenn jede neue Funktion Änderungen in mehreren Klassen erfordert, ist Ihr Design nicht flexibel genug. Gut designte Systeme wachsen durch Addition, nicht durch Modifikation bestehender Komponenten.
Liskov Substitution Prinzip
Unterklassen müssen ihre Basisklassen ersetzen können ohne das Programmverhalten zu ändern. Vererbung sollte eine ist-ein Beziehung darstellen. Wenn eine Unterklasse Methoden der Basisklasse nicht sinnvoll implementieren kann, ist die Vererbungshierarchie falsch. Quadrat ist kein Rechteck im Programmierkontext, weil es unterschiedliche Verhaltensbeschränkungen hat. Composition over Inheritance löst viele Probleme dieser Art elegant.
Dependency Inversion Prinzip
High-level Module sollten nicht von Low-level Modulen abhängen. Beide sollten von Abstraktionen abhängen. Injizieren Sie Abhängigkeiten statt sie direkt zu instanziieren. Dependency Injection macht Code testbar, weil Sie Abhängigkeiten durch Mocks ersetzen können. Ein Controller sollte nicht direkt eine Datenbankklasse instanziieren, sondern ein Repository-Interface nutzen. Ihre Anwendungslogik bleibt unabhängig von Implementierungsdetails konsequent.