Darauf gibt es keine eindeutige Antwort. Obwohl die Frage eng ist, sind die Erklärungen nicht.
Für mich ist es so etwas wie Occams Rasiermesser, wenn Sie wollen. Es ist ein Ideal, an dem ich versuche, meinen aktuellen Code zu messen. Es ist schwer, es in einfachen Worten festzunageln. Eine andere Metapher wäre »ein Thema«, das so abstrakt, dh schwer zu fassen ist wie »einzelne Verantwortung«. Eine dritte Beschreibung wäre »sich mit einer Abstraktionsebene befassen«.
Was heißt das konkret?
In letzter Zeit verwende ich einen Codierungsstil, der hauptsächlich aus zwei Phasen besteht:
Phase I lässt sich am besten als kreatives Chaos beschreiben. In dieser Phase schreibe ich Code auf, während die Gedanken fließen - dh roh und hässlich.
Phase II ist das genaue Gegenteil. Es ist wie nach einem Hurrikan aufzuräumen. Dies erfordert die meiste Arbeit und Disziplin. Und dann betrachte ich den Code aus der Sicht eines Designers.
Ich arbeite jetzt hauptsächlich in Python, so dass ich später an Objekte und Klassen denken kann. Erste Phase I - Ich schreibe nur Funktionen und verteile sie fast zufällig in verschiedenen Modulen. In Phase II , nachdem ich die Dinge in Gang gesetzt habe, sehe ich mir genauer an, welches Modul sich mit welchem Teil der Lösung befasst. Und während ich durch die Module blättere, tauchen für mich Themen auf. Einige Funktionen sind thematisch verwandt. Das sind gute Kandidaten für Klassen . Und nachdem ich Funktionen in Klassen umgewandelt habe - was fast mit Einrücken und Hinzufügen self
zur Parameterliste in Python erledigt ist ;) - verwende ich SRP
wie Occam's Razor, um Funktionen für andere Module und Klassen zu entfernen.
Ein aktuelles Beispiel ist möglicherweise das Schreiben einer kleinen Exportfunktion .
Es wurden CSV- , Excel- und kombinierte Excel-Tabellen in einem Reißverschluss benötigt.
Die einfache Funktionalität wurde jeweils in drei Ansichten (= Funktionen) durchgeführt. Jede Funktion verwendete eine gemeinsame Methode zum Bestimmen von Filtern und eine zweite Methode zum Abrufen der Daten. In jeder Funktion fand dann die Vorbereitung des Exports statt und wurde als Antwort vom Server geliefert.
Es waren zu viele Abstraktionsebenen verwechselt:
I) Umgang mit eingehenden / ausgehenden Anfragen / Antworten
II) Bestimmen von Filtern
III) Abrufen von Daten
IV) Umwandlung von Daten
Der einfache Schritt bestand darin, exporter
in einem ersten Schritt mit einer Abstraktion ( ) die Schichten II-IV zu behandeln.
Es blieb nur das Thema Anfragen / Antworten . Auf der gleichen Abstraktionsebene werden Anforderungsparameter extrahiert, was in Ordnung ist. Also ich hatte für diese Ansicht eine "Verantwortung".
Zweitens musste ich den Exporteur auflösen, der, wie wir sahen, aus mindestens drei weiteren Abstraktionsebenen bestand.
Das Bestimmen von Filterkriterien und der tatsächliche Abruf erfolgen nahezu auf derselben Abstraktionsebene (die Filter werden benötigt, um die richtige Teilmenge der Daten zu erhalten). Diese Ebenen wurden in so etwas wie eine Datenzugriffsschicht gelegt .
Im nächsten Schritt zerlegte ich die eigentlichen Exportmechanismen: Wo das Schreiben in eine temporäre Datei erforderlich war, zerlegte ich das in zwei "Verantwortlichkeiten": eine für das eigentliche Schreiben der Daten auf die Festplatte und eine andere, die sich mit dem eigentlichen Format befasste.
Mit der Bildung der Klassen und Module wurde klarer, was wohin gehörte. Und immer die latente Frage, ob die Klasse zu viel macht .
Wie legen Sie fest, welche Verantwortlichkeiten jede Klasse haben soll, und wie definieren Sie eine Verantwortlichkeit im Kontext der SRP?
Es ist schwer, ein Rezept zu geben, dem man folgen kann. Natürlich könnte ich die kryptische »Eine Abstraktionsebene« wiederholen - Regel, wenn das hilft.
Meistens ist es für mich eine Art "künstlerische Intuition", die zum aktuellen Design führt; Ich modelliere Code, wie ein Künstler Ton formen oder malen kann.
Stell dir mich als Coding vor Bob Ross ;)