Single Responsibility Principle (SRP) in der Softwareentwicklung

Ein Fachbeitrag von Hero Wanders, Senior Software Developer im Bereich Manufacturing 

Was genau steckt hinter dem Begriff Single Responsibility Principle (SRP)? Wie setzt man es bei der Softwareentwicklung ein? Das erläutern wir in diesem Blogbeitrag. 

Warum eine Definition von SRP so schwer fällt 

 Fragt man Entwicklerinnen und Entwickler, was das Single Responsibility Principle ist, so bekommt man sehr unterschiedliche Antworten. Zu den am häufigsten genannten Formulierungen gehört diese, die gelegentlich auch an die Unix-Philosophie angelehnt wird: 

A class/function should do only one thing [and do it well].” „Eine Klasse/Funktion sollten nur eine Sache tun [und dies gut machen].“ 

Verfolgt man den Ursprung des Begriffes SRP, so stößt man unweigerlich auf Robert C. Martin alias „Uncle Bob“. Er ist Mitbegründer des Agilen Manifests, das heutzutage als Fundament agiler Softwareentwicklung verstanden wird. Auch die Clean-Code-Initiative wurde nicht zuletzt durch seine Bücher maßgeblich vorangetrieben. In seinem Artikel „The Principles of OOD“ prägte er 2003 den Begriff des SRP. Dort heißt es jedoch: 

“A class should have one, and only one, reason to change.” „Es sollte nie mehr als einen Grund geben, eine Klasse zu ändern.“ 

Dies ist ein völlig anderes Kriterium als das zuerst genannte. Über die Jahre hinweg folgten weitere Charakterisierungen von ihm, wie zum Beispiel 2014 

Gather together the things that change for the same reasons. Separate those things that change for different reasons.”„Fasse die Dinge zusammen, die sich aus den gleichen Gründen ändern. Separiere die Dinge, die sich aus unterschiedlichen Gründen ändern.“ 

mit diesen Ergänzungen: 

This principle is about people. „Bei diesem Prinzip geht es um Menschen.“ 

Remember that the reasons for change are people. It is people who request changes.” „Bedenke, dass der Grund für Änderungen im Menschen liegt. Es sind Menschen, die Änderungen fordern.“ 

In seinem Buch „Clean Architecture” schreibt er dann 2017: 

A module should be responsible to one, and only one, actor.” „Ein Modul sollte einem, und nur einem, Akteur gegenüber verantwortlich sein.“ 

Aufgrund der verschiedenen Formulierungen und Interpretationen sind die Schwierigkeiten, dies alles unter einen Hut zu bringen, nachvollziehbar. Unter Entwicklern hat sich eine eher diffuse Intuition darüber etabliert, wie das SRP umzusetzen ist und Gespräche zur Einhaltung des SRP führen dazu, dass unterschiedliche Sichtweisen aufeinanderprallen. 

Nachfolgend wollen wir eine Möglichkeit aufzeigen, wie man das SRP verstehen kann – und zwar in einer Weise, die zu Uncle Bobs Charakterisierungen passt, aber dabei auch praktisch anwendbar ist. 

Der Mythos des Single Responsibility Principle bringt so viele Fragen mit sich, dass man sich am besten schrittweise nähert. 

  • Worauf bezieht sich das SRP? Klassen, Funktionen, Module? 
  • Was steckt hinter den einzelnen Begriffen „Single“, „Responsibility“, „Principle“? 
  • Was setzt man mit Code eigentlich um? 
  • Warum verändert sich Code und was hat das mit Menschen zu tun? 
Diskussionsgegenstand des SRP 

Zunächst zielt das SRP auf Programmcode ab. Bei der Entwicklung entstehen verschiedene Code-Strukturen, wie etwa Funktionen, Klassen und Dateien, die dann weiter in Ordnern und Namensräumen, Komponenten oder ganzen Services bzw. Programmen zusammengefasst werden. 

Diese Struktureinheiten wollen wir hier im Artikel vereinfachend Code-Container nennen. 

Das SRP macht eine Aussage über eine Eigenschaft von Code-Containern. 

Wir übernehmen also nicht die in den üblichen SRP-Formulierungen auftauchenden Begriffe wie „class“, „module“ oder „function“, weil sie unnötig spezifisch sind und Diskussionen anregen, die tatsächlich vom eigentlichen Thema wegführen. 

Bedeutung der Begriffe im SRP 

Einzeln betrachtet sind die drei Begriffe „Single“, „Responsibility“ und „Principle“ verständlich. Bezogen auf die Entwicklung von Software können wir die Begriffe aber etwas genauer fassen: 

Principle: 

  • Ein abzuwägendes Gebot, also eine Richtlinie zur Beschreibung der gewünschten Ausgestaltung des Codes – keine Regel oder Gesetz! Es wird angestrebt, dass der Code gewissen Kriterien genügt. Genauer gesagt geht es darum, dass jeder Code-Container eine gewisse Eigenschaft auf bestimmte Weise erfüllen soll: 

Single (…): 

  • Code-Container sollen möglichst nur eine Ausprägung eines bestimmten Merkmals haben. 
    Es soll eine Eindeutigkeit hergestellt werden, und zwar geht es um dieses Merkmal: 

Responsibility: 

  • Code-Containern wird eine bestimmte Verantwortlichkeit übertragen.  
    Dabei geht es im weitesten Sinne um die Herstellung bestimmter Effekte. 
    Aber wer oder was definiert eigentlich was ein Code-Container tun soll? 

Der Dreh- und Angelpunkt, die Responsibility, bleibt so erstmal weiterhin mysteriös. 
Der Zusammenhang zwischen Verantwortlichkeiten und Veränderungen (siehe „reasons to change“) ist auch noch nicht offensichtlich. Wir müssen noch tiefer graben und verstehen, was Verantwortlichkeiten sind: 

Wenn wir über Software sprechen, dann geht es um die automatisierte Durchführung bestimmter Vorgänge. Was da genau durchgeführt wird, wurde zuvor entschieden und man baut darauf, dass dies auch zuverlässig geschieht. Kurzum: 

Eine Verantwortlichkeit zu haben, bedeutet eine Entscheidung zuverlässig durchzusetzen. Code soll also Entscheidungen durchsetzen. 

Da Entscheidungen häufig von Menschen getroffen werden und änderbar sind, entfaltet sich nun die ganze Bedeutung des SRP. Die kompakten, aber wie sich herausstellt, treffenden Charakterisierungen von Uncle Bob können aufgeklärt werden. Dazu formulieren wir das SRP zunächst neu: 

Das SRP umformuliert 

Das SRP ist ein Prinzip zur Strukturierung von Code, der Entscheidungen umsetzt: 

Es soll eine 1:1-Korrespondenz zwischen Entscheidungen und den verantwortlichen Code-Containern hergestellt werden. 

Das heißt: 

  • Für jede Entscheidung gibt es nur einen Code-Container, der für die Umsetzung verantwortlich ist. 
  • Jeder Code-Container ist primär für die Umsetzung einer definierten Entscheidung zuständig. 

Wenn Code nach diesem Muster aufgebaut wird, ist das SRP erfüllt. 

Diese Formulierung lässt noch einige praktische Fragen offen, beispielsweise ob und wie sich die angedeutete Code-Container-Hierarchie in den Entscheidungen widerspiegelt. Für eine Vertiefung des Verständnisses wollen wir nun darauf schauen, wie Entscheidungen strukturiert sind, wer sie trifft und schließlich, wann sie sich ändern. 

Was sind Entscheidungen? 

Eine Entscheidung ist eine Festlegung auf eine Option von mehreren möglichen. Die Art und Bandbreite der Optionen aus denen ausgewählt wird, der Entscheidungsspielraum, in dem sich die Auswahl bewegt, kann unterschiedlich aussehen: 

  • Sein oder nicht sein? Berücksichtigen wir etwas oder nicht? 
  • Auswahl aus klar bestimmten Alternativen (abgestuft oder diskret) 
  • Auswahl aus einer unendlichen Menge von Möglichkeiten (kontinuierlich) 

Eine Entscheidung kann oft als Antwort auf eine Frage formuliert werden. So eine Antwort kann besagte Auswahl oder aber auch eine Verfahrensbeschreibung zum Finden der Antwort sein, abhängig von einer einflussnehmenden Situation. Beispielsweise lesen sich solche Fragen wie folgt: 

  • Soll das Programm/Feature/Detail überhaupt entwickelt werden oder bewusst ausgelassen werden? 
  • Welche unserer vier Finanzierungsverfahren werden dem Kunden angeboten? 
  • Wie hoch ist der angebotene Kreditrahmen? Unter welchen Konditionen? 

Neben der Entscheidung dafür, was erreicht werden soll, stellt sich auch immer die Frage nach dem Weg dahin, dem Wie. Bei der Umsetzung von Software müssen besonders viele solche Wie-Entscheidungen getroffen werden, die nicht Teil der fachlichen Betrachtungen sind. 

Dabei heißt es stets mit Blick auf das SRP genau hinzusehen, um zu treffende Entscheidungen und die möglichen Optionen zu erkennen. Das erfordert Fantasie und Gründlichkeit während der Anforderungsanalyse und Umsetzung. 

Da Entscheidungen später aufgrund zahlreicher Einflussfaktoren oft nicht mehr ohne Weiteres nachvollziehbar sind, sollte der konkrete Grund für die getroffene Entscheidung dokumentiert werden, selbst dann, wenn dadurch die Existenz von Code negiert wird. 

Entscheidungen in Code umsetzen 

Je nach Art und Quelle der Entscheidung kann sich die Umsetzung in Form von Code auf verschiedene Weisen darstellen. Wir betrachten hier exemplarisch einige der zuvor genannten Entscheidungstypen und wie sie in Code-Containern realisiert werden: 

Positive Entscheidungen zur Durchführung eines Vorhabens werden typischerweise durch die Existenz eines entsprechenden Dienstes oder Programms mit einem ausführbaren Einstiegspunkt repräsentiert. Negative Existenzentscheidungen sind allerdings im Code meist nicht zu finden. Wie so oft ist hier eine klare Informationsweitergabe bis in die Entwicklung relevant, die dort oder in einer externen Dokumentation in einer entsprechenden Kommentierung reflektiert werden kann.  

Die Entscheidung, überhaupt auf etwas zu reagieren oder umgekehrt etwas Messbares zu bewirken, wird durch die Schaffung von Schnittstellen zu Hardware (Eingabe und Ausgabe) bzw. zu anderer dafür verantwortlicher Software umgesetzt. Darunter fallen Schnittstellen zur Netzwerkkommunikation, klassische Peripheriegeräte wie Maus und Tastatur und vieles mehr. Eine besondere Eingabe ist das Erzeugen einer zufälligen Zahl oder das Auslesen der aktuellen Uhrzeit. Nach dem SRP sind diese Umsetzungen in separaten Code-Containern zu implementieren, aber es wird keine Aussage darüber getroffen, welcher Art diese Container sein sollen. Andere Prinzipien, die eine klare Trennung von Code mit Seiteneffekten und funktional gestaltetem Code favorisieren oder die die deterministische Testbarkeit zum Ziel erklären, geben hier klarere Richtlinien. 

In Programmen gibt es zahlreiche Schritte, die klären auf welche Weise eine Entscheidung erreicht wird. Auch hier streifen wir andere Clean-Code-Prinzipien, aber es sei angemerkt, dass verschiedene Erkenntnis- oder Aufbereitungsschritte ebenfalls als eigene Code-Container repräsentiert werden können. Sie sind Teil der Umsetzung eines Entscheidungsverfahrens, auch wenn es erst von der Entwicklerin bzw. dem Entwickler im Detail aufgestellt wurde. Die wesentlichen Schritte sollten hierbei im Code deutlich voneinander separiert sein. Beispielsweise kann die Uminterpretation einer Mitarbeiteranzahl als Zahl zu buchender Sitzplätze explizit ausformuliert werden, indem hierfür eine neue Variable eingeführt wird. 

Werden im Code Entscheidungen getroffen, die durch äußere Faktoren beeinflusst werden, die erst „zur Laufzeit“ feststehen, so kann dies im verantwortlichen Code-Container durch Parameter (z. B. Funktions- oder Konstruktorparameter) dargestellt werden. 

Wenn auf Basis einer Eingabe aus einer endlichen Zahl von Optionen eine bestimmte gewählt werden soll, so kann dies unter anderem mit den klassischen if/switch-Kontrollstrukturen oder dem Abruf aus einer vorher befüllten Entscheidungstabelle realisiert werden. Das Strategy-Pattern ermöglicht es zwischen alternativen Verfahren zu wählen, die später verwendet werden. 

Bei der Ermittlung eines Wertes aus einem Kontinuum wird meist eine Berechnung oder Transformation durchgeführt, häufig mit Hilfe von Parametern aus einem ebenfalls kontinuierlichen Wertebereich. 
Dabei werden in der Implementierung und dem Test oft sogenannte Äquivalenzklassen gebildet, etwa anhand von Bereichen, deren Behandlung jeweils gleichartig ist. Die Festlegung der Grenzen ist, ob fachlich oder technisch getrieben, sofern nicht selbstevident, wieder eine Entscheidung bzw. eine Erkenntnis auf dem Weg dahin – und kann als Konstante mit fachlichem Namen im Code festgehalten werden (einem sehr kleinen Code-Container). 

Als Tipp sei hier mitgegeben, die Entscheidung für die eine oder andere Option bzw. den Wert eines Steuerparameters von den Details der Weiterverwendung bzw. Durchführung eines gewählten Verfahrens zu trennen. Daran werden nämlich meist noch viele weitere Verantwortlichkeiten geknüpft, deren Umsetzungen nach dem SRP nicht vermischt werden sollen. Das Integration-Operation-Segregation-Principle gibt hier weitere Hinweise zur Ausgestaltung dieser Trennung. 

Entscheidungen und deren Umsetzung strukturieren 

Da die Strukturierung von Code-Containern für Entwicklerinnen und Entwickler zum Alltag gehört, lohnt sich im Kontext des SRP auch ein Blick auf die Struktur von Entscheidungen. 

Entscheidungen können zusammenhängen und bilden dadurch ein System. Auch wenn diese Zusammenhänge vielgestaltig sein können, so lässt sich doch häufig eine dominierende Hierarchie finden, die man zur Strukturierung heranziehen möchte. 

Beispielsweise ergibt sich die Notwendigkeit eine Entscheidung zu treffen oft durch die Wahl einer „übergeordneten“ Entscheidung. Die konkrete Gestaltung einer solchen Entscheidungshierarchie ist aufgrund der vielen möglichen Betrachtungsweisen aber nicht direkt vorgegeben, sondern eine kreative Tätigkeit, deren Ergebnisse umsetzungsfördernd, aber auch hemmend sein können. 

Hat man allerdings erst einmal eine Entscheidungshierarchie aufgebaut, so ergibt sich durch die Entwicklung eine Verantwortlichkeitshierarchie, in der die Entscheidungen den umsetzenden Code-Containern zugeordnet werden. Das SRP wird befolgt, wenn diese Zuordnung strukturerhaltend ist, also die Code-Container in Zahl und Anordnung möglichst genau die Entscheidungen widerspiegelt. Dadurch bleibt der Code begründet und nachvollziehbar. 

Die Entscheidungshierarchie soll mit der Code-Container-Hierarchie korrespondieren. 

Die Erhaltung von Strukturen ist ein Prinzip, das oft angewendet wird, wenn komplexe Modelle ineinander überführt und dabei wichtige Informationen nicht verloren gehen sollen. 

Um nichts anderes geht es hier nämlich: nicht-ausführbare Entscheidungssysteme in eine von Computern ausführbare Form zu bringen. Das SRP hilft uns dabei, Letzteres zu gestalten. 

Wie wir sehen, gibt es verschiedene Arten von Code-Containern, deren Größe sich dem obigem Vorgehen zufolge nach dem Umfang der Entscheidung richten soll. Da es in Programmiersprachen nur eine kleine Anzahl verschiedener Code-Container-Arten gibt, ist hier eine gewisse Kreativität gefragt und Dopplungen lassen sich nicht vermeiden. Das kann in einigen Fällen die Verständlichkeit etwas schmälern. 

Das kann zum Beispiel so aussehen: 

  • Services/Programme repräsentieren ganze Vorhaben 
  • Verzeichnisse und Namespaces stellen oft größere, existenzielle Entscheidungen über Unterthemengebiete dar, oft vielfach verschachtelt 
  • Klassen bündeln die Umsetzung verwandter Entscheidungen, die mit den gleichen Daten arbeiten 
  • Funktionen setzen einzelne Verfahren um. Da auch in Verfahren wieder viele Entscheidungen getroffen werden müssen, rufen Funktionen wiederum weitere Funktionen auf 
  • Die allerkleinsten Entscheidungen sind einzelne Codezeilen, Properties, Ausdrücke und Konstanten 

Da allgemeine Programmiersprachen nicht domänenspezifisch sind und selbst in der Theorie aufgrund vieler möglichen Perspektiven fast niemals die eine ideale Modellierung möglich ist, lässt sich die Korrespondenz nicht perfekt umsetzen. Das SRP bietet aber immerhin eine Richtschnur an. 

Die Welt steht nicht still, alles ändert sich 

Da Organisationen jeder Art durch steten Wandel einem Druck zur Anpassung und Optimierung unterliegen, wirkt sich dies auch auf die Software aus, die zur Bewältigung der Herausforderungen eingesetzt wird. Früher getroffene Entscheidungen können aus verschiedenen Gründen überarbeitet oder verworfen werden, neue Entscheidungen kommen hinzu. Der verantwortliche Code soll der veränderten Lage dann entsprechend folgen. Dies effizient und korrekt zu leisten, stellt bei komplexen Software-Systemen schon immer eine besondere Schwierigkeit dar. 

Die Strukturierung von Code entlang der getroffenen Entscheidungen erleichtert durch den starken Fokus nicht nur die initiale Entwicklung, sondern verbessert auch die Wartbarkeit: 

Wenn direkt klar ist, welcher Code bei Entscheidungsänderungen anzupassen ist oder wo neuer Code ergänzt werden muss, weil ein weiteres Detail einer übergeordneten Entscheidung festgelegt wurde, bleiben bei der Entwicklung viele langwierige Recherchen erspart. Auch unnötige gewordene Entscheidungen können durch Löschung des verantwortlichen Codes und dessen Integration leichter wieder entfernt werden, als wenn diese verteilt oder ggf. sogar implizit im Code sind. 

Nun stehen Entscheidungen aber nicht alle unabhängig für sich und sie entwickeln sich auch nicht alle unabhängig voneinander weiter. Die schon angesprochenen Beziehungen zwischen Entscheidungen führen zwangsläufig dazu, dass sich Änderungen daran in gewissem Rahmen auf andere Entscheidungen auswirken, auch über die Zusammenhänge hinweg, die nicht in der primären Hierarchie abgebildet wurden. Dies lässt sich nicht vermeiden und betrifft grundsätzlich jede Art von komplexem System. In allen modellierenden Disziplinen, vom Requirements Engineering über Software-Design bis zum Team-Management, werden daher Techniken zur Vermeidung und Steuerung von Abhängigkeiten eingesetzt. Bei der Gestaltung eines Software-Systems müssen hier alle zusammenarbeiten. 

Nach Robert C. Martin soll Code für Entscheidungen, die von den gleichen Menschen getroffen werden oder gemeinsam geändert werden, gruppiert werden. 

Dies ist ein pragmatischer Ansatz, der die Realität ständiger Änderung akzeptiert und den wichtigsten Initiator für Änderungen direkt identifiziert: Letztlich entscheiden Menschen über die in ihrer Verantwortung liegenden Fragestellungen, meist eines ganzen Themenbereichs. Es liegt nahe, dass hier Beziehungen bestehen und Änderungen gemeinsam passieren. Im Common Closure Principle führt Robert C. Martin dieses Prinzip noch weiter. 

Werden Entscheidungen und dann Code entsprechend strukturiert, so wird zumindest tendenziell kein Übermaß an neuen Abhängigkeiten und Querbeziehungen eingeführt, das nur der Implementierung geschuldet ist. Änderungen bleiben dann eher „lokaler“ Art und pflanzen sich nicht kaskadenartig durch die ganze Code-Basis fort. 

Einer der vielen Stakeholder sind die Entwicklerinnen und Entwickler selbst. Durch kurze Innovationszyklen in der Technik und notwendigerweise eingegangene Abhängigkeiten zu technischen Details, liegen hier zum Teil völlig andere Beweggründe für Änderungen vor, als dies in der Fachdomäne der Fall ist. 

Viele technische Aspekte haben keinen eindeutigen Platz im fachlich orientierten Entscheidungsbaum, sondern sind in einer anderen Hierarchie untergebracht. 

Dem SRP konsequent folgend, ergibt sich: 

Die Umsetzung von technischen und fachlichen Entscheidungen soll im Code klar getrennt werden. 

Sehr plastisch dargestellt wird dies in der Onion Architecture (und den verwandten Ansätzen der Hexagonal-undClean Architecture). Dort werden der Infrastruktur-Code und Domänen-Code explizit verschiedenen Schichten zugeordnet. Die Domäne wird dabei ins Zentrum gestellt, in dessen Richtung alle Abhängigkeiten zeigen, auch weil im Zweifel eher eine geänderte Fachlichkeit Auswirkungen auf die technischen Details haben soll als umgekehrt. Der eigentliche Wert der entwickelten Applikation liegt häufig in der Automatisierung der Kerndomäne und ist daher besonders schützenswert gegenüber unerwünschten Einflüssen. 

Wann wird das SRP eingehalten?  

Grundsätzlich kann man die Einhaltung des SRP bewerten, indem man prüft, wie stringent die Korrespondenz zwischen Entscheidungen und Code-Containern eingehalten wird. 

Eine nachvollziehbare Bewertung ist am ehesten möglich, wenn getroffene Entscheidungen und ihre Zusammenhänge tatsächlich dokumentiert werden. 

Obwohl die Dokumentation von Entscheidungen zahlreiche positive Effekte mit sich bringt und auch im technischen Umfeld als Good Practice gilt, findet man jedoch nur selten einen dedizierten Entscheidungsbaum. Viel häufiger wird der Code auf Basis nur schwach strukturierter Anforderungsbeschreibungen entwickelt, sodass es beim Abgleich viele Unsicherheiten gibt: 

  • Anforderungen werden von unterschiedlichen Menschen verschieden interpretiert. 
  • Entscheidungen werden erkannt oder nicht erkannt. 
  • Der Entscheidungsbaum wird unterschiedlich aufgebaut. 
  • Der Detailgrad wird unterschiedlich weit getrieben. 

Auch bei der Umsetzung völlig klarer fachlicher Entscheidungen gibt es keinen „Königsweg“ zum Aufbau des Codes: 

  • Die Zuordnung von Entscheidungen zu Verantwortlichkeiten im Code ist zum Teil ein kreativer Prozess. 
  • Technische Entscheidungen können vielfältig ausfallen, klare Leitlinien fehlen häufig. 

Wie gut das SRP umgesetzt wurde kann man also nur bewerten, wenn man die Entscheidungen und ihre Zusammenhänge wirklich kennt und versteht. Dies ist kein Zustand, den man einmal erreicht und dann automatisch behält, sondern das Ergebnis eines fortwährenden Abgleichs mit den tatsächlichen Bedürfnissen und Anforderungen an die Software. Ohne Zutun erodiert das Verständnis tatsächlich, etwa durch simples Vergessen, Ausscheiden von Beschäftigten, unreflektierten Änderungen von Anforderungen oder Techniken und vielen weiteren Gründen. 

Um das SRP dauerhaft umzusetzen, muss der Code mit der Entwicklung des Verständnisses gemeinsam geändert werden. 

Das Fazit 

Code soll Entscheidungen umsetzen und das SRP empfiehlt hierbei, eine klare Korrespondenz aufzubauen. Dass jeder Code-Container für die Umsetzung genau einer (single) Entscheidung verantwortlich (responsible) ist, wird hierbei zum strukturgebenden Prinzip (principle) erklärt. 

Allein die Befolgung dieses Prinzips hat einige nützliche Effekte: 

  • Verständlichkeit: Code-Container haben einen deutlichen Zweck. 
  • Änderbarkeit: Zu verändernder/ergänzender Code kann leicht lokalisiert werden. 
  • Zuverlässigkeit: Ein starker Fokus macht eine korrekte Umsetzung wahrscheinlich. 
  • Testbarkeit: An Entscheidungsumsetzung orientierte Tests haben einen klaren Testgegenstand. 

Wie jedes Prinzip sollte auch dieses jedoch nicht zum einzig maßgeblichen Prinzip oder gar einem Dogma erklärt werden, denn es unterstützt nur einige der in der Software-Entwicklung angestrebten Ziele. Die Abwägung aller Ziele ist unerlässlich, eines davon ist die langfristige Schaffung von Werten. 

Die Überprüfung und dauerhafte Einhaltung des Prinzips macht eine intensive Beschäftigung mit den Anforderungen und den darin gefällten Entscheidungen erforderlich, doch stärkt dies auch genau die nötige Nähe und Bezogenheit von Software zu ihrem eigentlichen Zweck. 

—– 

Grundlage für diesen Beitrag sind die Arbeiten zum SRP von Ralf Westphal aus dem Jahr 2020, die er auf der .NET Developer Conference 2020 in einem Vortrag präsentierte und im Artikel „Das Single Responsibility Principle – Entmystifiziert“ vom 12. Oktober 2020 bei dotnetpro veröffentlichte.