SOLID-Prinzipien der objektorientierten Programmierung

Softwareentwicklung ist ein komplexer Prozess, der sorgfältige Planung, Architektur und Design erfordert. Eines der wichtigsten Ziele bei der Softwareentwicklung ist es, sicherzustellen, dass die Software flexibel, erweiterbar und nachhaltig ist. Hier kommen die SOLID-Prinzipien ins Spiel, bei denen es sich um eine Reihe von fünf Grundprinzipien der objektorientierten Programmierung (OOP) handelt, die dazu beitragen, qualitativ hochwertige und gut skalierbare Software zu erstellen. Diese Prinzipien wurden von Robert C. Martin vorgeschlagen und sind unter dem Akronym SOLID bekannt. In diesem Artikel werden wir einen detaillierten Blick auf jedes dieser Prinzipien werfen.

Gut gemachte Software braucht eine gute Codebasis, die leicht zu lesen, zu verstehen, zu pflegen (Funktionen hinzufügen/ändern, Fehler beheben) und für die Zukunft erweiterbar ist. Das spart Entwicklungszeit und Ressourcen.

SOLID-Prinzipien des OOP:

S – Prinzip der einzigen Verantwortung

O – Prinzip offen/geschlossen L – Prinzip der Liskov-Substitution I – Prinzip der Schnittstellentrennung D – Prinzip der Abhängigkeitsinversion

Single Responsibility Principle (SRP) – Prinzip der einzigen Verantwortung

Das Prinzip der Einzelverantwortung besagt, dass jedes Modul, jede Klasse oder Funktion in einem Computerprogramm für einen Teil der Funktionalität dieses Programms verantwortlich sein sollte. Ebenso sollten sie diesen Teil kapseln, und ihre Dienste sollten eng mit dieser Verantwortung verknüpft sein. Dies stellt sicher, dass Klassen kleiner, übersichtlicher, leichter verständlich sind und die Wartung des Codes einfacher ist. Wenn eine Klasse mehrere Aufgaben ausführt, wird sie komplex und fehleranfällig.

Beispiele für Verantwortlichkeiten, die in Software im Allgemeinen getrennt werden müssen: Formatierung, Parsing, Mapping, Validierung, Protokollierung, Persistenz, Benachrichtigung, Fehlerbehandlung, Klassenauswahl/Instanz usw.

Open/Closed Principle (OCP) – Prinzip der Offenheit und Geschlossenheit

Das Prinzip der Offenheit und Geschlossenheit besagt, dass Module, Klassen und Funktionen offen für Erweiterungen und geschlossen für Änderungen sein sollten. Das bedeutet, dass wir in der Lage sein sollten, das Verhalten eines Moduls oder einer Klasse zu ändern, ohne deren Quellcode ändern zu müssen. Dies erreichen wir durch den Einsatz von Schnittstellen, abstrakten Klassen oder Vererbung. Auf diese Weise minimieren wir das Risiko, beim Hinzufügen neuer Funktionen Fehler in den bestehenden Code einzubauen.

Wie Sie OCP anwenden:

Fügen Sie neue Funktionen hinzu, indem Sie neue abgeleitete Klassen erstellen, die von der ursprünglichen Basisklasse erben und dem Client den Zugriff auf die ursprüngliche Klasse über eine abstrakte Schnittstelle mittels kompositorischer Entwurfsmuster wie dem Strategy-Muster ermöglichen. Anstatt die bestehende Funktionalität zu ändern, erstelle neue abgeleitete Klassen und lasse die ursprüngliche Implementierung der Klasse unverändert. Dieses Prinzip wird verletzt, wenn Sie die Basisklasse ändern müssen.

Liskov Substitution Principle (LSP) – Das Liskovsche Substitutionsprinzip

Das Liskovsche Substitutionsprinzip besagt, dass ein Objekt einer bestimmten Klasse durch eine Instanz seiner abgeleiteten Klassen ersetzt werden können sollte, ohne dass sich das Verhalten des Programms ändert. Das bedeutet, dass, wenn wir eine Klasse A haben und von dieser eine abgeleitete Klasse B, wir B überall dort verwenden können sollten, wo wir ein Objekt vom Typ A erwarten. Dieses Prinzip stellt sicher, dass Vererbung und Polymorphismus korrekt und konsistent funktionieren.

Wenn wir ein Objekt bzw. eine Instanz einer Elternklasse erfolgreich durch ein Objekt bzw. eine Instanz einer abgeleiteten Klasse ersetzen können, ohne das Verhalten der Instanz der Basisklasse zu beeinflussen, dann halten wir das Liskov Substitutionsprinzip (LSP) ein. Wenn dieses Prinzip verletzt wird, führt dies in der Regel zu vielen zusätzlichen bedingten Logiken, die im gesamten Anwendungscode verstreut sind und überprüfen, ob ein Objekt von einem bestimmten Typ ist.

Mit zunehmender Größe der Anwendung wird der duplizierte und verstreute Code zu einer Brutstätte für Fehler. Eine sehr häufige Verletzung dieses Prinzips ist die Teilimplementierung von Schnittstellen oder Funktionen der Basisklasse, bei der nicht alle Methoden oder Eigenschaften implementiert werden und stattdessen eine Ausnahme geworfen wird (zum Beispiel NotImplementedException).

Solche Implementierungen gehören nicht in Code, der an Dritte geliefert wird.
Solche Implementierungen gehören nicht in Code, der an Dritte geliefert wird.

Bei Code, von dem Sie wissen, dass er nur von einem einzigen Kunden verwendet wird, den Sie überwachen können, ist das in Ordnung. Aber im gemeinsam genutzten Code oder noch schlimmer in einem Framework, das an Dritte geliefert wird, sollten solche Implementierungen nicht vorkommen.

Wenn eine Schnittstelle mehr Funktionen hat, als Sie benötigen, verwenden Sie das Prinzip der Schnittstellentrennung (ISP), um eine neue Schnittstelle zu erstellen, die nur die Funktionen enthält, die Ihr Client-Code benötigt und die Sie vollständig implementieren können.

Interface Segregation Principle (ISP) – Prinzip der Schnittstellentrennung

Das Prinzip der Schnittstellentrennung besagt, dass wir eher mehrere spezifische Schnittstellen als eine große, generische Schnittstelle erstellen sollten. Das hilft uns, Abhängigkeiten zu minimieren und sicherzustellen, dass Klassen nur die Methoden implementieren, die sie benötigen, und nicht gezwungen sind, unnötige Methoden zu implementieren. Einfach ausgedrückt: Kunden sollten nicht gezwungen werden, Methoden zu implementieren, die sie nicht nutzen.

Dependency Inversion Principle (DIP) – Prinzip der Abhängigkeitsumkehr

Das Prinzip der umgekehrten Abhängigkeit besagt, dass Module/Klassen auf einer höheren Ebene nicht von Modulen/Klassen auf einer niedrigeren Ebene abhängen sollten. Stattdessen sollten beide von Abstraktionen abhängen. Weiterhin sollten Abstraktionen nicht von Implementierungsdetails abhängen; diese Details sollten von Abstraktionen abhängen.

Wenn eine Klasse das Design und die Implementierung einer anderen Klasse kennt, erhöht sich das Risiko, dass Änderungen in einer Klasse die andere Klasse beeinträchtigen. Versuche immer, Module/Klassen auf verschiedenen Ebenen so wenig wie möglich miteinander zu verbinden. Um dies zu erreichen, müssen wir beide von Abstraktionen abhängig machen, anstatt uns gegenseitig zu kennen. Auf diese Weise erreichen wir, dass der Code flexibel ist und leicht geändert werden kann, ohne dass Sie alle Stellen ändern müssen, an denen die Klasse verwendet wird.

Fazit

Software-Designprinzipien sind Empfehlungen, die Programmierer bei der Erstellung von Software befolgen, um sauberen und nachhaltigen Code zu erzeugen. Es handelt sich um eine Sammlung von Techniken und Best Practices, die von vielen bekannten Experten und Autoren der Branche empfohlen werden.

Die SOLID-Prinzipien der objektorientierten Programmierung stellen einen wichtigen Bestandteil des objektorientierten Softwaredesigns dar. Die Einhaltung dieser Prinzipien hilft uns, qualitativ hochwertigen, nachhaltigen und leicht erweiterbaren Code zu erstellen. Das Prinzip der einzigen Verantwortung stellt sicher, dass Klassen eine einzige Verantwortung haben. Das Open/Closed-Prinzip ermöglicht es uns, das Verhalten von Klassen zu ändern, ohne den Code zu modifizieren. Das Liskov-Substitutionsprinzip stellt sicher, dass wir abgeleitete Klassen anstelle der Elternklasse verwenden können. Das Prinzip der Schnittstellentrennung hilft uns, die Abhängigkeiten zwischen Klassen zu minimieren. Das Prinzip der Inversion von Abhängigkeiten stellt sicher, dass wir von Abstraktionen und nicht von konkreten Implementierungen abhängig sind.

Beherrscht du die SOLID-Prinzipien und die Programmiersprache Java? Wenn du auf der Suche nach einem Job als Java Entwickler bist, schau dir unsere Mitarbeiterbenefits an und bewirb dich auf die neuesten Stellenangebote.

Über den Autor

Jozef Wagner

Java Developer Senior

Viac ako 10 rokov programujem v Jave, momentálne pracujem v msg life Slovakia ako Java programátor senior a pomáham zákazníkom implementovať ich požiadavky do poistného softvéru Life Factory. Vo voľnom čase si rád oddýchnem v lese, prípadne si zahrám nejakú dobrú počítačovú hru.

Informieren Sie uns über sich