IEC 61131-3: SOLID – Fünf Grundsätze für bessere Software

Neben der Syntax einer Programmiersprache und dem Verständnis der wichtigsten Bibliotheken und Frameworks, gehören weiterer Methodiken – wie zum Beispiel Design Pattern – zu den Grundlagen der Softwareentwicklung. Neben den Design Pattern sind Designprinzipien ebenfalls ein hilfreiches Werkzeug bei der Entwicklung von Software. SOLID ist ein Akronym für fünf solcher Designprinzipien, die dem Entwickler dabei unterstützen Software verständlicher, flexibler und wartbarer zu entwerfen.

In größeren Softwareprojekten existiert eine Vielzahl von Funktionsblöcken, die über Vererbung und Referenzen miteinander in Verbindung stehen. Durch die Aufrufe der Funktionsblöcke und deren Methoden agieren diese Einheiten untereinander. Dieses Zusammenspiel der Codeeinheiten, kann bei falschem Design das Erweitern oder Auffinden von Fehlern unnötig erschweren. Für die Entwicklung von nachhaltiger Software sollten die Funktionsblöcke so modelliert werden, damit diese einfach zu erweitern sind.

Viele Design Pattern wenden die SOLID-Prinzipien an, um für die jeweilige Aufgabenstellung einen Architekturansatz vorzuschlagen. Die SOLID-Prinzipien sind auch nicht als Regeln zu verstehen, sondern mehr als Ratschläge. Sie sind eine Untermenge vieler Prinzipien, die der amerikanische Software-Ingenieur und Dozent Robert C. Martin (auch bekannt als Uncle Bob) in seinem Buch (Amazon-Werbelink *) Clean Architecture: Das Praxis-Handbuch für professionelles Softwaredesign vorgestellt hat. Die SOLID-Prinzipien sind im Einzelnen:

  • Single Responsibility Principle (SRP)
  • Open/Closed Principle (OCP)
  • Liskov Substitution Principle (LSP)
  • Interface Segregation Principle (ISP)
  • Dependency Inversion Principle (DIP)

Die hier gezeigten Prinzipien sind Hinweise, die es einem Entwickler erleichtert die Codequalität zu verbessern. Der Aufwand amortisiert sich nach kurzer Zeit, da Änderungen einfacher, Tests und Fehlersuche beschleunigt werden. Somit sollte das Wissen über diese fünf Designprinzipien zur Basis eines jeden Softwareentwicklers gehören.

Single Responsibility Principle (SRP)

Ein Funktionsblock sollte nur eine einzige Verantwortung haben. Wird die Funktionalität eines Programms geändert, sollte dieses nur Auswirkungen auf wenige Funktionsblöcke haben. Viele kleine Funktionsblöcke, sind besser als wenige große. Der Code wirkt auf dem ersten Blick zwar umfangreicher, ist dadurch aber einfacher zu organisieren. Ein Programm mit vielen kleineren Funktionsblöcken, für jeweils spezielle Aufgaben, ist einfacher zu pflegen, als wenige große Funktionsblöcke, die den Anspruch erheben, alles zu können.

Open/Closed Principle (OCP)

Nach dem Open/Closed Principle sollten Funktionsblöcke offen für Erweiterungen, aber geschlossen für Änderungen sein. Die Umsetzung von Erweiterungen sollte nur durch Hinzufügen von Code, nicht durch Ändern von vorhandenen Code erreicht werden. Ein gutes Beispiel für dieses Prinzip ist die Vererbung. Ein neuer Funktionsblock erbt von einem schon vorhandenen Funktionsblock. Neue Funktionen können so hinzugefügt werden, ohne den vorhanden Funktionsblock verändern zu müssen. Es muss nicht einmal der Programmcode vorliegen.

Liskov Substitution Principle (LSP)

Das Liskov Substitution Principle fordert, dass abgeleitete Funktionsblöcke immer anstelle ihrer Basis-FBs einsetzbar sein müssen. Abgeleitete FBs müssen sich so verhalten wie ihr Basis-FB. Ein abgeleiteter FB darf den Basis-FB erweitern, aber nicht einschränken.

Interface Segregation Principle (ISP)

Viele kundenspezifische Schnittstellen sind besser als eine Universalschnittstelle. Eine Schnittstelle darf demnach nur die Funktionen enthalten, die auch wirklich eng zusammengehören. Durch umfangreiche Schnittstellen entstehen Kopplungen zwischen ansonsten unabhängigen Programmteilen. Somit hat das Interface Segregation Principle, ein ähnliches Ziel wie das Single Responsibility Principle. Allerdings gibt es bei der Umsetzung dieser beiden Prinzipien unterschiedliche Ansätze.

Dependency Inversion Principle (DIP)

Funktionsblöcke sind häufig linear in einer Richtung voneinander abhängig. Ein Funktionsblock für das Loggen von Meldungen, ruft Methoden eines anderen Funktionsblocks auf, um Daten in eine Datenbank zu schreiben. Zwischen dem Funktionsblock für das Loggen und dem Funktionsblock für den Zugriff auf die Datenbank besteht eine feste Abhängigkeit. Das Prinzip der Abhängigkeitsinversion löst diese feste Abhängigkeit auf, indem eine gemeinsame Schnittstelle definiert wird. Diese wird von dem Baustein für die Datenbankzugriffe implementiert.

Zum Schluss

In den folgenden Posts werde ich die einzelnen SOLID-Prinzipen genauer vorstellen und versuchen diese anhand eines Beispiels zu erläutern. Als Grundlage dient hierbei das Beispiel-Programm aus meinem Post IEC 61131-3: Das Command Pattern. Mit jedem SOLID-Prinzip will ich versuchen das Programm weiter zu optimieren.

Starten werde ich in Kürze mit dem Dependency Inversion Principle (DIP).

Author: Stefan Henneken

I’m Stefan Henneken, a software developer based in Germany. This blog is just a collection of various articles I want to share, mostly related to Software Development.

One thought on “IEC 61131-3: SOLID – Fünf Grundsätze für bessere Software”

  1. Hi Stefan,
    I find the idea with an example program super and can hardly wait.
    Design patterns are so important for a machine that has been in the field for a long time and will experience some changes over the years.

Leave a comment