1. Prinzip einer einzigen Verantwortung
Das Single Responsibility Principle (SRP) besagt, dass jedes Modul einer Software (in Java also die Klassen und Methoden) genau eine Verantwortung übernehmen soll.
Es gilt auch der Umkehrschluss: Jede Verantwortung soll nur durch ein Modul realisiert werden.

Schlechtes und gutes Beispiel zum SRP, nach Martin 1997 [4]
Autor: Ulrich Helmich 2025, Lizenz: Public domain
Dieses Bild zeigt links ein schlechtes Beispiel, das sich nicht an das Prinzip der alleinigen Verantwortung hält. Eine Klasse Rectangle stellt zwei Methoden zur Verfügung, nämlich draw() und area(). Die Methode draw() stellt das Rechteck graphisch dar, während area() den Flächeninhalt berechnet und als double-Wert zurückgibt.
Die draw()-Methode wird von einer Graphik-Anwendung aufgerufen, die area()-Methode von einer Mathematik-Anwendung.
Wenn sich nun beispielsweise die Anforderungen der Mathematik-Anwendung ändern, kann es sein, dass die Klasse Rectangle angepasst werden muss. Durch unsachgemäße Änderungen kann sich das aber ungewollt auch auf die Graphik-Anwendung auswirken, die dann nicht mehr fehlerfrei funktioniert.
Im Bild rechts sehen wir eine bessere Variante. Es existieren zwei Klassen für Rechtecke, nämlich Rectangle, die für die graphische Darstellung verantwortlich ist und MathRectangle, die für mathematische Berechnungen verantwortlich ist. Sollten sich nun die Anforderungen der Mathe-Anwendung ändern, so muss nur die Klasse MathRectangle angepasst werden. Auf die Graphik-Anwendung hat das keine Auswirkungen mehr.
Weitere Informationen zu diesem Grundprinzip finden Sie auf dieser Seite.
2. Trennung der Anliegen
Das Separation of Concerns (SOC) - Prinzip besagt, dass ein Anliegen durch genau ein Modul repräsentiert werden und nicht über mehrere Module verstreut sein soll. Ein Anliegen ist dabei "eine formulierbare Aufgabe eines Programms, die zusammenhängend und abgeschlossen ist" [1].
Ein Beispiel aus der Folge 5 des Kurses - Musikverwaltung
- Die Klasse MusicTrack speichert nur die Daten eines Musiktitels: Titel, Interpret, Jahr
- Die Klasse MusicCollection verwaltet eine Liste von MusicTrack-Objekten – sie implementiert die Logik der Sammlung.
- Die Methode showTrackInfo() ausschließlich für die Darstellung der Daten in einem GUI (Graphic user interface) zuständig.
Ein Verstoß gegen dieses Prinzip wäre es, wenn MusicTrack selbst für die Darstellung in dem GUI zuständig wäre.
3. Wiederholungen vermeiden
Wenn in einem Quelltext immer wieder die gleichen Abfolgen von Anweisungen vorkommen, dann kann man diese in einem eigenen Modul zusammenfassen. Das verkürzt den Quelltext und verringert die Fehleranfälligkeit. Bei Änderung der Anforderungen muss dann nur das neue Modul angepasst werden und nicht mehr jede Stelle im Quelltext, das die wiederholten Anweisungen enthält.
"Eine identifizierbare Funktionalität eines Softwaresystems sollte innerhalb dieses Systems nur einmal umgesetzt sein." [1]
4. Offen für Erweiterungen, geschlossen für Änderung
Oft muss ein- und dasselbe Modul in verschiedenen Umgebungen eingesetzt werden, in verschiedenen Programmen oder im gleichen Programm unter verschiedenen Betriebssystemen.
Das naheliegende Verfahren ist es, dieses Modul zu kopieren und dann an die neue Umgebung anzupassen.
Dieses Verfahren birgt aber einige Risiken. Wenn sich die Anforderungen an dieses Modul ändern, müssen alle Kopien entsprechend verändert werden. Dabei kann es zu Inkonsistenzen und entsprechenden Fehlern kommen.
Ein Modul soll für Erweiterungen offen sein, aber nicht indem das Modul geändert wird, sondern indem es mit Erweiterungsmodulen gekoppelt wird, die entsprechend angepasst werden können.
"Das Modul soll also definierte Erweiterungspunkte bieten, an die sich die Erweiterungsmodule anknüpfen lassen." [1]
5. Trennung von Schnittstelle und Implementation
Program to Interfaces
Dies ist ein relativ einfaches Prinzip. Jedes Modul darf nur über eine klar definierte Schnittstelle mit anderen Modulen kommunizieren. In Java wären das die Signaturen der Methoden mit ihren Parametern sowie die Festlegung der Funktionalität des jeweiligen Moduls.
Wird dieses Prinzip konsequent befolgt, kann ein Modul leicht durch ein verändertes / verbessertes Modul mit der gleichen Schnittstelle ausgetauscht werden.
Die Implementierung dieser Module spielt dabei keine Rolle, sie ist im Innern des Moduls verborgen (Datenkapselung).
6. Umkehr der Abhängigkeiten
Dependency Inversion Principle
Eine Anwendung wie beispielsweise eine Wetter-App nutzt in der Regel eine Grafikbibliothek des Betriebssystems, um Wetterdaten grafisch darzustellen – etwa in Form eines Balkendiagramms. Dazu ruft sie explizit Funktionen dieser Bibliothek auf.
Wenn jedoch das Fenster der App vergrößert oder verkleinert wird, muss das Betriebssystem die App darüber informieren, damit diese ihre Darstellung anpassen kann. In diesem Fall ruft nicht die App die Bibliothek auf, sondern das Framework des Betriebssystems ruft die App auf – dies ist eine Umkehrung des Kontrollflusses (Inversion of Control bzw. Hollywood-Prinzip: "Don't call us, we'll call you!").
7. Testbarkeit
Unit-Tests
Einzelne Module einer Anwendung sollten sich unabhängig voneinander testen lassen.
Dabei kann die Entwicklung von Testmodulen durchaus aufwendiger sein als die Entwicklung der einzelnen zu testenden Module, da ja viele verschiedene Fälle und Situationen überprüft werden müssen.
In BlueJ kann man sich für jede Klasse eine Testunit generieren lassen, die dann solche Tests automatisch durchführt - allerdings nur für einzelne Situationen, die man selbst in der Testunit implementieren muss.
Einfacher ist es oft, eine eigene Testklasse zu programmieren, mit der man die zu überprüfende Klasse testen kann.
Quellen:
- Lahres et al.: Objektorientierte Programmierung, Rheinwerk Computing 2021.
- Barnes, Kölling: Java lernen mit BlueJ - Objects first. Pearson-Verlag 2019.
- Ullenboom: Java ist auch eine Insel, Rheinwerk Computing 2023.
- Robert C. Martin: SRP: The Single Responsibility Principle. Februar 1997