{"id":34828,"date":"2019-10-31T22:00:38","date_gmt":"2019-10-31T19:00:38","guid":{"rendered":"https:\/\/prohoster.info\/blog\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya\/"},"modified":"2019-10-31T22:00:38","modified_gmt":"2019-10-31T19:00:38","slug":"single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya","title":{"rendered":"Einfaches Verantwortungsprinzip. Nicht so einfach, wie es scheint","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Einfaches Verantwortungsprinzip. Nicht so einfach, wie es scheint\" src=\"\/wp-content\/uploads\/2019\/06\/5b253ff55e3c97b6baf5f7a7ae7f3b98.JPG\" style=\"display:block;margin: 0 auto;\" \/> Prinzip der einzelnen Verantwortung, auch bekannt als Prinzip der einzelnen Verantwortung,<br \/>\ndas auch als Prinzip der einzelnen Ver\u00e4nderlichkeit bekannt ist \u2013 ein sehr rutschiger und schwer verst\u00e4ndlicher Begriff und eine so nervenaufreibende Frage im Vorstellungsgespr\u00e4ch f\u00fcr Programmierer. <\/p>\n<p><\/p>\n<p>Meine erste ernsthafte Begegnung mit diesem Prinzip fand zu Beginn des ersten Semesters statt, als wir, jung und unerfahren, in den Wald gebracht wurden, um aus Larven von Studenten \u2013 echte Studenten \u2013 zu machen.<\/p>\n<p><\/p>\n<p>Im Wald wurden wir in Gruppen von 8-9 Personen eingeteilt und es fand ein Wettbewerb statt \u2013 welche Gruppe schneller eine Flasche Wodka leert, unter der Bedingung, dass die erste Person aus der Gruppe den Wodka ins Glas einschenkt, die zweite ihn trinkt und die dritte nachschl\u00e4gt. Die Person, die ihre Aufgabe abgeschlossen hat, reiht sich am Ende der Schlange der Gruppe ein. <\/p>\n<p><\/p>\n<p>Ein Fall, bei dem die Gr\u00f6\u00dfe der Schlange ein Vielfaches von drei war, stellte eine gute Umsetzung des SRP dar.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex> <\/p>\n<h2 id=\"opredelenie-1-edinaya-otvetstvennost\">Definition 1. Einzige Verantwortung.<\/h2>\n<p><\/p>\n<p>Offizielle Definition des Prinzips der einzelnen Verantwortung (SRP): Jeder Objekt hat seine eigene Verantwortung und einen Grund f\u00fcr seine Existenz, und diese Verantwortung ist die einzige.<\/p>\n<p><\/p>\n<p>Betrachten wir das Objekt \"Vypivokha\" (<strong>Tippler<\/strong>).<br \/>\nUm das SRP-Prinzip einzuhalten, teilen wir die Aufgaben auf drei Personen auf: <\/p>\n<p><\/p>\n<ul>\n<li>Einer schenkt ein (<strong>PourOperation<\/strong>)<\/li>\n<li>Einer trinkt (<strong>DrinkUpOperation<\/strong>)<\/li>\n<li>Einer bei\u00dft (<strong>TakeBiteOperation<\/strong>)<\/li>\n<\/ul>\n<p><\/p>\n<p>Jeder der Teilnehmer des Prozesses ist f\u00fcr eine Komponente des Prozesses verantwortlich, das hei\u00dft, hat eine atomare Verantwortung \u2013 zu trinken, zu gie\u00dfen oder nachzuschlagen. <\/p>\n<p><\/p>\n<p>Der Wodkatrinker ist in diesem Fall das Interface f\u00fcr diese Operationen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">class Tippler {\n    \/\/...\n    void Act() {\n        _pourOperation.Do() \/\/ gie\u00dfen\n        _drinkUpOperation.Do() \/\/ trinken\n        _takeBiteOperation.Do() \/\/ nachschlagen\n    }\n}<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Einfaches Verantwortungsprinzip. Nicht so einfach, wie es scheint\" src=\"\/wp-content\/uploads\/2019\/06\/8d591a474e3555edfee3ffebc28d079b.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h4 id=\"zachem\">Warum?<\/h4>\n<p><\/p>\n<p>Der Programmierer schreibt Code f\u00fcr den Affen, und der Affe ist unaufmerksam, dumm und st\u00e4ndig in Eile. Er kann etwa 3 bis 7 Begriffe zu einem Zeitpunkt halten und verstehen.<br \/>\nIm Fall des Wodkatrinkers sind es diese drei Begriffe. Wenn wir jedoch gesamten Code in einem St\u00fcck schreiben, tauchen H\u00e4nde, Gl\u00e4ser, Schl\u00e4gereien und endlose Diskussionen \u00fcber Politik auf. Und all dies wird im K\u00f6rper einer Methode sein. Ich bin mir sicher, dass Sie solchen Code in Ihrer Praxis gesehen haben. Kein sehr humanes Experiment f\u00fcr die Psyche.<\/p>\n<p><\/p>\n<p>Andererseits ist der Mensch-Affe darauf konzentriert, Objekte der realen Welt in seinem Kopf zu modellieren. In seiner Vorstellung kann er sie zusammensto\u00dfen, neue Objekte daraus erschaffen und sie ebenso wieder auseinandernehmen. Stellen Sie sich ein altes Automodell vor. Sie k\u00f6nnen sich vorstellen, die T\u00fcr zu \u00f6ffnen, die T\u00fcrverkleidung abzuschrauben und die Mechanismen der Fensterheber zu sehen, in denen Zahnr\u00e4der sind. Aber Sie k\u00f6nnen nicht alle Komponenten des Autos gleichzeitig in einem \"Listing\" sehen. Zumindest kann das der \"Mensch-Affe\" nicht.<\/p>\n<p><\/p>\n<p>Deshalb zerlegen Programmierer komplexe Mechanismen in eine Menge weniger komplexer und funktionierender Elemente. Allerdings kann man unterschiedlich zerlegen: In vielen alten Autos f\u00fchrt der Luftkanal in die T\u00fcr, w\u00e4hrend in modernen Autos ein Elektronikfehler im Schloss den Motorstart verhindert, was bei der Reparatur Schwierigkeiten verursacht.<\/p>\n<p><\/p>\n<p>Also, <strong>SRP ist ein Prinzip, das erkl\u00e4rt, WIE man zerlegt, also wo man die Trennlinie ziehen sollte.<\/strong>. <\/p>\n<p><\/p>\n<p>Er sagt, dass man nach dem Prinzip der \"Verantwortungsteilung\" decomponieren sollte, also nach den Aufgaben der jeweiligen Objekte.<\/p>\n<p>\n<img decoding=\"async\" alt=\"Einfaches Verantwortungsprinzip. Nicht so einfach, wie es scheint\" src=\"\/wp-content\/uploads\/2019\/06\/b1980c3dc9742b921eb818f14fe3527e.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Kehren wir zu dem Trinker und den Vorteilen zur\u00fcck, die der Mensch-Affe beim Zerlegen erh\u00e4lt: <\/p>\n<p><\/p>\n<ul>\n<li>Der Code ist auf jeder Ebene extrem klar.<\/li>\n<li>Der Code kann von mehreren Programmierern gleichzeitig geschrieben werden (jeder schreibt ein separates Element).<\/li>\n<li>Automatisierte Tests werden einfacher - je einfacher das Element, desto leichter ist es, es zu testen.<\/li>\n<li>Es entsteht eine Kompositionalit\u00e4t des Codes - man kann ersetzen. <strong>DrinkUpOperation<\/strong> durch eine Operation, bei der der Trinker Fl\u00fcssigkeit unter den Tisch gie\u00dft. Oder man kann die Einschenken-Operation durch eine Operation ersetzen, bei der man Wein und Wasser oder Wodka und Bier mischt. Je nach den Anforderungen des Gesch\u00e4fts k\u00f6nnen Sie alles tun, ohne den Codes des Verfahrens zu ber\u00fchren. <strong>Tippler.Act<\/strong>. <\/li>\n<li>Aus diesen Operationen k\u00f6nnen Sie eine Verschwendung zusammenstellen (indem Sie nur <strong>TakeBitOperation<\/strong>), einen Alkoholiker (indem Sie nur <strong>DrinkUpOperation<\/strong> direkt aus der Flasche) und viele andere Gesch\u00e4ftsanforderungen zufriedenstellen.<\/li>\n<\/ul>\n<p><\/p>\n<p><em>(Oh, das scheint bereits das OCP-Prinzip zu sein, und ich habe die Verantwortung dieses Beitrags verletzt.) <\/em><\/p>\n<p><\/p>\n<p>Und nat\u00fcrlich die Nachteile: <\/p>\n<p><\/p>\n<ul>\n<li>Es m\u00fcssen mehr Typen geschaffen werden. <\/li>\n<li>Der Trinker wird das erste Mal ein paar Stunden sp\u00e4ter trinken, als er k\u00f6nnte.<\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"opredelenie-2-edinaya-izmenchivost\">Definition 2. Einzigartige \u00c4nderbarkeit.<\/h2>\n<p><\/p>\n<p>Eure Exzellenzen! Die Klasse Vypivokha hat ebenfalls eine einheitliche Verantwortung \u2013 sie trinkt! Und \u00fcberhaupt ist das Wort \"Verantwortung\" ein \u00e4u\u00dferst vages Konzept. Jemand ist f\u00fcr das Schicksal der Menschheit verantwortlich, w\u00e4hrend jemand anders daf\u00fcr verantwortlich ist, die umgefallenen Pinguine am Pol aufzuheben.<\/p>\n<p><\/p>\n<p>Betrachten wir zwei Implementierungen des Trinkers. Die erste, die oben erw\u00e4hnt wurde, umfasst drei Klassen \u2013 einschenken, trinken und snacken.<\/p>\n<p><\/p>\n<p>Die zweite ist durch die Methodologie \"Vorw\u00e4rts und nur vorw\u00e4rts\" geschrieben und enth\u00e4lt die gesamte Logik in der Methode. <strong>Act<\/strong>:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">\/\/\u041d\u0435 \u0442\u0440\u0430\u0442\u044c\u0442\u0435 \u0432\u0440\u0435\u043c\u044f  \u043d\u0430 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430. \u041b\u0443\u0447\u0448\u0435 \u0441\u044a\u0435\u0448\u044c\u0442\u0435 \u043f\u0435\u0447\u0435\u043d\u044c\u043a\u0443\n\u0441lass BrutTippler {\n   \/\/...\n   void Act(){\n        \/\/ \u043d\u0430\u043b\u0438\u0432\u0430\u0435\u043c\n    if(!_hand.TryDischarge(from:_bottle, to:_glass, size:_glass.Capacity))\n        throw new OverdrunkException();\n\n    \/\/ \u0432\u044b\u043f\u0438\u0432\u0430\u0435\u043c\n    if(!_hand.TryDrink(from: _glass,  size: _glass.Capacity))\n        throw new OverdrunkException();\n\n    \/\/\u0417\u0430\u043a\u0443\u0441\u044b\u0432\u0430\u0435\u043c\n    for(int i = 0; i&lt; 3; i++){\n        var food = _foodStore.TakeOrDefault();\n        if(food==null)\n            throw new FoodIsOverException();\n\n        _hand.TryEat(food);\n    }\n   }\n}<\/code><\/pre>\n<p><\/p>\n<p>Beide Klassen, aus Sicht eines externen Beobachters, sehen absolut identisch aus und erf\u00fcllen die einheitliche Verantwortung \"trinken\". <\/p>\n<p><\/p>\n<p>Peinlich!<\/p>\n<p><\/p>\n<p>Dann gehen wir ins Internet und erfahren eine andere Definition des SRP \u2013 Prinzip der einzigen \u00c4nderbarkeit (Single Changeability Principle).<\/p>\n<p><\/p>\n<p>SCP besagt, dass \"<strong>Ein Modul hat einen und nur einen Grund zur \u00c4nderung<\/strong>\". Das hei\u00dft, \"Verantwortung ist ein Grund f\u00fcr Ver\u00e4nderung\". <\/p>\n<p><\/p>\n<p><em>(Es scheint, dass die Leute, die die urspr\u00fcngliche Definition erfunden haben, von den telepathischen F\u00e4higkeiten des Menschenaffen \u00fcberzeugt waren)<\/em><\/p>\n<p><\/p>\n<p>Jetzt passt alles an seinen Platz. Man kann die Einschenk-, Trink- und Snackprozesse separat \u00e4ndern, und im eigentlichen Trinker k\u00f6nnen wir nur die Reihenfolge und den Inhalt der Vorg\u00e4nge \u00e4ndern, zum Beispiel indem wir den Snack vor dem Trinken anordnen oder das Vorlesen eines Trinkspruchs hinzuf\u00fcgen.<\/p>\n<p><\/p>\n<p>Im Ansatz \"Vorw\u00e4rts und nur vorw\u00e4rts\" kann alles, was ver\u00e4ndert werden kann, nur in der Methode ge\u00e4ndert werden. <strong>Act<\/strong>. Das kann lesbar und effizient sein, wenn es nur wenig Logik gibt und sie sich selten \u00e4ndert, aber oft endet das in schrecklichen Methoden mit 500 Zeilen in jeder, mit mehr if-Anweisungen als erforderlich f\u00fcr den Beitritt Russlands zur NATO. <\/p>\n<p><\/p>\n<h2 id=\"opredelenie-3-lokalizaciya-izmeneniy\">Definition 3. Lokalisierung von \u00c4nderungen.<\/h2>\n<p><\/p>\n<p>Trinker verstehen oft nicht, warum sie in einer fremden Wohnung aufgewacht sind oder wo ihr Handy ist. Es ist an der Zeit, detailliertes Logging hinzuzuf\u00fcgen.<\/p>\n<p><\/p>\n<p>Lassen Sie uns das Logging mit dem Einschenkprozess beginnen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">class PourOperation: IOperation{\n    PourOperation(ILogger log \n    \/*....*\/){\n    \/*...*\/}\n    \/\/...\n    void Do(){\n        _log.Log($\"Vor dem Einschenken mit {_hand} und {_bottle}\");\n        \/\/Einschank-Logik ...\n        _log.Log($\"Nach dem Einschenken mit {_hand} und {_bottle}\");\n    }\n}<\/code><\/pre>\n<p><\/p>\n<p>indem wir es in <strong>PourOperation<\/strong>, wir haben klug in Bezug auf Verantwortung und Kapselung gehandelt, aber nun haben wir ein Problem mit dem Prinzip der Ver\u00e4nderlichkeit. Neben der Operation, die sich \u00e4ndern kann, wird auch das Logging selbst variabel. Wir m\u00fcssen trennen und einen speziellen Logger f\u00fcr die Gie\u00dfoperation erstellen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">interface IPourLogger{\n    void LogBefore(IHand, IBottle){}\n    void LogAfter(IHand, IBottle){}\n    void OnError(IHand, IBottle, Exception){}\n}\n\nclass PourOperation: IOperation{\n    PourOperation(IPourLogger log \/*....*\/){\/*...*\/}\n    \/\/...\n    void Do(){\n        _log.LogBefore(_hand, _bottle);\n        try{\n             \/\/... Gesch\u00e4ftslogik\n             _log.LogAfter(_hand, _bottle);\n        }\n        catch(exception e){\n            _log.OnError(_hand, _bottle, e)\n        }\n    }\n}<\/code><\/pre>\n<p><\/p>\n<p>Ein genauer Leser wird bemerken, dass <strong>LogAfter<\/strong>, <strong>LogBefore<\/strong> und <strong>OnError<\/strong> auch einzeln variieren k\u00f6nnen, und analog zu den vorherigen Aktionen drei Klassen erstellen wird: <strong>PourLoggerBefore<\/strong>, <strong>PourLoggerAfter<\/strong> und <strong>PourErrorLogger<\/strong>.<\/p>\n<p><\/p>\n<p>Und wenn wir uns erinnern, dass es drei Arten von Trinkoperationen gibt, erhalten wir neun Logging-Klassen. Insgesamt besteht unser Trink-Framework aus 14 (!!!) Klassen.<\/p>\n<p><\/p>\n<p>Hyperbel? Kaum! Ein Mensch-Affenkind mit einer dekompositionellen Granate wird den \u201eGie\u00dfer\u201c in Karaffe, Glas, Einspeisefunktionen, Wasserdienste, physikalische Molek\u00fclkollisionsmodelle zerlegen und das n\u00e4chste Quartal damit verbringen, Abh\u00e4ngigkeiten ohne globale Variablen zu entwirren. Und glauben Sie mir \u2013 er wird nicht aufh\u00f6ren.<\/p>\n<p><\/p>\n<p>Gerade in diesem Punkt kommen viele zu dem Schluss, dass SRP M\u00e4rchen aus rosa K\u00f6nigreichen sind, und sie gehen los, um Kabel zu wickeln\u2026<\/p>\n<p><\/p>\n<p>\u2026 und erfahren nie von der Existenz der dritten Definition von SRP: <\/p>\n<p><\/p>\n<p>\"Das Prinzip der einheitlichen Verantwortung besagt, dass <strong>\u00e4hnliche \u00c4nderungsobjekte an einem Ort aufbewahrt werden sollten\u201c<\/strong>\". Oder \"<strong>Was zusammen ge\u00e4ndert wird, sollte an einem Ort aufbewahrt werden.<\/strong>\u201d<\/p>\n<p><\/p>\n<p>Das hei\u00dft, wenn wir das Logging der Operation \u00e4ndern, m\u00fcssen wir dies an einem Ort tun.<\/p>\n<p><\/p>\n<p>Das ist ein sehr wichtiger Punkt \u2013 denn alle vorherigen Erkl\u00e4rungen von SRP besagten, dass Typen so lange fragmentiert werden m\u00fcssen, wie sie fragmentierbar sind, was ein \"oberen Einschr\u00e4nkung\" auf die Gr\u00f6\u00dfe des Objekts auferlegte, und jetzt sprechen wir bereits von einer \"unteren Einschr\u00e4nkung\". Mit anderen Worten, <strong>SRP verlangt nicht nur \"so lange zu fragmentieren, wie es fragmentierbar ist\", sondern auch, dass man nicht \u00fcbertreiben sollte \u2013 \"einander verbundene Dinge nicht zu sehr fragmentieren\".<\/strong>. Das ist der gro\u00dfe Kampf zwischen Ockhams Rasiermesser und dem Menschen-Affen!<\/p>\n<p>\n<img decoding=\"async\" alt=\"Einfaches Verantwortungsprinzip. Nicht so einfach, wie es scheint\" src=\"\/wp-content\/uploads\/2019\/06\/2e349a5b119a511d716341f3f6725844.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Jetzt sollte es f\u00fcr den Trinkenden einfacher werden. Neben der Tatsache, dass wir den Logger IPourLogger nicht in drei Klassen zerlegen m\u00fcssen, k\u00f6nnen wir auch alle Logger in einem Typ zusammenfassen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">class OperationLogger{\n    public OperationLogger(string operationName){\n        \/*..*\/\n    }\n    public void LogBefore(object[] args){\n        \/*...*\/\n    }\n    public void LogAfter(object[] args){\n        \/*..*\/\n    }\n    public void LogError(object[] args, exception e){\n        \/*..*\/\n    }\n}<\/code><\/pre>\n<p><\/p>\n<p>Und wenn uns ein vierter Operationstyp hinzugef\u00fcgt wird, ist das Logging daf\u00fcr bereits vorbereitet. Und der Code der Operationen selbst ist sauber und frei von infrastrukturellem L\u00e4rm.<\/p>\n<p><\/p>\n<p>Insgesamt haben wir 5 Klassen zur L\u00f6sung der Trinkaufgabe:<\/p>\n<p><\/p>\n<ul>\n<li>Abf\u00fclloperation<\/li>\n<li>Trinkoperation<\/li>\n<li>Abbei\u00dfoperation<\/li>\n<li>Logger<\/li>\n<li>Spirituosen-Fassade<\/li>\n<\/ul>\n<p><\/p>\n<p>Jede dieser Klassen ist streng f\u00fcr eine Funktionalit\u00e4t verantwortlich und hat einen einzigen Grund zur \u00c4nderung. Alle \u00e4hnlichen \u00c4nderungsregeln liegen nah beieinander. <\/p>\n<p>\n<b class=\"spoiler_title\">Beispiel aus dem echten Leben<\/b><\/p>\n<p>Einmal haben wir einen Service zur automatischen Registrierung von b2b-Kunden geschrieben. Und es entstand eine GOD-Methode mit 200 Zeilen \u00e4hnlichen Inhalts:<\/p>\n<p><\/p>\n<ul>\n<li>Geh zu 1C und lege ein Konto an<\/li>\n<li>Gehe mit diesem Konto zum Zahlungsmodul und lege es dort an<\/li>\n<li>\u00dcberpr\u00fcfe, ob ein Konto mit diesem Konto im Hauptsystem nicht existiert <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/de\/server\/dts-dronten\/\"   title=\"Server\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"2485\">Server<\/a><\/li>\n<li>Erstelle ein neues Konto<\/li>\n<li>F\u00fcge das Ergebnis der Registrierung im Zahlungsmodul und die 1C-Nummer dem Registrierungsservice hinzu<\/li>\n<li>F\u00fcge diese Tabelle mit Informationen \u00fcber das Konto hinzu<\/li>\n<li>Erstelle eine Punktnummer f\u00fcr diesen Kunden im Punkteservice. \u00dcbergebe die 1C-Nummer an diesen Service.<\/li>\n<\/ul>\n<p><\/p>\n<p>In dieser Liste gab es noch etwa 10 weitere Gesch\u00e4ftsoperationen mit schrecklicher Verkn\u00fcpfung. Das Kontoobjekt war fast \u00fcberall erforderlich. Die Punkt-ID und der Kundenname waren in der H\u00e4lfte der Aufrufe n\u00f6tig.<\/p>\n<p><\/p>\n<p>Nach einer einst\u00fcndigen Refaktorisierung konnten wir den Infrastrukturcode und einige Nuancen der Kontobearbeitung in separate Methoden\/Klassen auslagern. Die God-Methode wurde leichter, aber es blieben 100 Zeilen Code, die sich einfach nicht aufl\u00f6sen wollten. <\/p>\n<p><\/p>\n<p>Erst nach einigen Tagen kam das Verst\u00e4ndnis, dass die Essenz dieser \"erleichterten\" Methode \u2013 der Business-Algorithmus ist. Und dass die urspr\u00fcngliche Beschreibung des Lastenhefts ziemlich komplex war. Und gerade der Versuch, diese Methode in St\u00fccke zu zerlegen, wird eine Verletzung von SRP sein, und nicht umgekehrt. <\/p>\n<p><\/p>\n<h2 id=\"formalizm\">Formalisierung.<\/h2>\n<p><\/p>\n<p>Es ist an der Zeit, unseren Spirituosenverk\u00e4ufer ruhen zu lassen. Wisch dir die Tr\u00e4nen weg \u2013 wir werden eines Tages zu ihm zur\u00fcckkehren. Aber jetzt formalisiere ich das Wissen aus diesem Artikel. <\/p>\n<p><\/p>\n<h4 id=\"formalizm-1-opredelenie-srp\">Formalisierung 1. Definition von SRP<\/h4>\n<p><\/p>\n<ol>\n<li>Trennt die Elemente so, dass jedes von ihnen f\u00fcr etwas Einziges verantwortlich ist.<\/li>\n<li>Verantwortung wird als \u201eAnlass zur \u00c4nderung\u201c entschl\u00fcsselt. Das bedeutet, dass jedes Element nur einen einzigen Anlass zur \u00c4nderung hat, im Sinne der Gesch\u00e4ftlogik.<\/li>\n<li>Potenzielle \u00c4nderungen der Gesch\u00e4ftslogik sollten lokalisiert werden. \u00c4nderbare synchronisierte Elemente sollten nah beieinander liegen.<\/li>\n<\/ol>\n<p><\/p>\n<h4 id=\"formalizm-2-neobhodimye-kriterii-samoproverki\">Formalismus 2. Notwendige Kriterien zur Selbstpr\u00fcfung.<\/h4>\n<p><\/p>\n<p>Mir sind keine ausreichenden Kriterien zur Erf\u00fcllung des SRP begegnet. Aber es gibt notwendige Bedingungen:<\/p>\n<p><\/p>\n<p>1) Stellen Sie sich die Frage \u2013 was macht diese Klasse\/Methode\/Modul\/Dienst? Sie sollten mit einer einfachen Definition darauf antworten. (Danke) <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/brightori\/\" class=\"user_link\">Brightori<\/a><\/noindex> )<\/p>\n<p>\n<b class=\"spoiler_title\">Erl\u00e4uterungen<\/b><\/p>\n<p>Manchmal ist es jedoch sehr schwierig, eine einfache Definition zu finden. <\/p>\n<p><\/p>\n<p>2) Die Behebung eines bestimmten Fehlers oder die Hinzuf\u00fcgung einer neuen Funktion betrifft die minimale Anzahl von Dateien\/Klassen. Ideal w\u00e4re \u2014 eine. <\/p>\n<p>\n<b class=\"spoiler_title\">Erl\u00e4uterungen<\/b><\/p>\n<p>Da die Verantwortung (f\u00fcr die Funktion oder den Fehler) in einer einzigen Datei\/Klasse gekapselt ist, wissen Sie genau, wo Sie suchen und was Sie \u00e4ndern m\u00fcssen. Zum Beispiel: Die Funktion zur \u00c4nderung der Ausgabe der Logoperations w\u00fcrde nur den Logger erfordern. Es ist nicht erforderlich, den gesamten restlichen Code zu durchforsten. <\/p>\n<p><\/p>\n<p>Ein anderes Beispiel \u2014 die Hinzuf\u00fcgung eines neuen UI-Elements, das den vorherigen \u00e4hnelt. Wenn Sie dadurch 10 verschiedene Entit\u00e4ten und 15 verschiedene Konverter hinzuf\u00fcgen m\u00fcssen, sieht es so aus, als h\u00e4tten Sie \"\u00fcbertrieben\".<\/p>\n<p><\/p>\n<p>3) Wenn mehrere Entwickler an verschiedenen Funktionen Ihres Projekts arbeiten, ist die Wahrscheinlichkeit eines Merge-Konflikts, also die Wahrscheinlichkeit, dass dieselbe Datei\/Klasse von mehreren Entwicklern gleichzeitig ge\u00e4ndert wird, minimal.<\/p>\n<p>\n<b class=\"spoiler_title\">Erl\u00e4uterungen<\/b><\/p>\n<p>Wenn Sie beim Hinzuf\u00fcgen einer neuen Operation \u201eWodka unter den Tisch gie\u00dfen\u201c den Logger, die Trink- und Ausgussoperation ber\u00fchren m\u00fcssen \u2013 dann scheint es, als ob die Verantwortungen falsch verteilt sind. Sicherlich ist das nicht immer m\u00f6glich, aber man sollte versuchen, diesen Wert zu minimieren. <\/p>\n<p><\/p>\n<p>4) Bei einer kl\u00e4renden Frage zur Gesch\u00e4ftslogik (vom Entwickler oder Manager) greifen Sie strikt auf eine einzige Klasse\/Datei zu und erhalten Informationen nur von dort.<\/p>\n<p>\n<b class=\"spoiler_title\">Erl\u00e4uterungen<\/b><\/p>\n<p>Funktionen, Regeln oder Algorithmen sind kompakt, jeweils an einem Ort geschrieben und nicht \u00fcber Flags im gesamten Code verstreut.<\/p>\n<p><\/p>\n<p>5) Die Benennung ist klar.<\/p>\n<p>\n<b class=\"spoiler_title\">Erl\u00e4uterungen<\/b><\/p>\n<p>Unsere Klasse oder Methode ist f\u00fcr etwas Bestimmtes verantwortlich, und diese Verantwortung spiegelt sich in ihrem Namen wider.<\/p>\n<p><\/p>\n<p>AllManagersManagerService \u2014 wahrscheinlich eine God-Klasse.<br \/>\nLocalPayment \u2014 wahrscheinlich nicht. <\/p>\n<p><\/p>\n<h4 id=\"formalizm-3-metodika-razrabotki-okkama-first\">Formalismus 3. Methode der Entwicklung \u201eOccam-first\u201c.<\/h4>\n<p><\/p>\n<p>Zu Beginn des Designs wei\u00df die Mensch-\u00c4ffchen nicht und sp\u00fcrt nicht alle Feinheiten der zu l\u00f6senden Aufgabe und kann einen Fehler machen. Man kann auf verschiedene Arten falsch liegen:<\/p>\n<p><\/p>\n<ul>\n<li>Zu gro\u00dfe Objekte erstellen, indem verschiedene Verantwortlichkeiten zusammengef\u00fcgt werden<\/li>\n<li>Zerlegen, indem eine einzige Verantwortung in viele verschiedene Typen aufgeteilt wird<\/li>\n<li>Verantwortungsgrenzen falsch definieren<\/li>\n<\/ul>\n<p><\/p>\n<p>Es ist wichtig, sich an die Regel zu erinnern: \u201eEs ist besser, zu viel zu irren\u201c oder \u201eWenn Sie sich nicht sicher sind \u2013 zerlegen Sie nicht\u201c. Wenn zum Beispiel Ihre Klasse zwei Verantwortlichkeiten vereint \u2013 dann ist sie immer noch verst\u00e4ndlich und kann mit minimalen \u00c4nderungen des Client-Codes in zwei Teile aufgeteilt werden. Es ist jedoch in der Regel schwieriger, aus Glasscherben ein Glas zu rekonstruieren, da der Kontext \u00fcber mehrere Dateien verteilt und die erforderlichen Abh\u00e4ngigkeiten im Client-Code fehlen. <\/p>\n<p><\/p>\n<h2 id=\"pora-zakruglyatsya\">Es ist an der Zeit, zum Ende zu kommen<\/h2>\n<p><\/p>\n<p>Der Anwendungsbereich des SRP ist nicht auf OOP und SOLID beschr\u00e4nkt. Es ist anwendbar auf Methoden, Funktionen, Klassen, Module, Mikrodienste und Dienste. Es findet Anwendung sowohl bei \"Fickfack-fickfack-und-in-Produktion\" als auch bei \"Raketenwissenschaft\"-Entwicklung und macht \u00fcberall die Welt ein kleines St\u00fcck besser. Wenn man dar\u00fcber nachdenkt, ist es kaum mehr als ein grundlegendes Prinzip der gesamten Ingenieurwissenschaften. Maschinenbau, Kontrollsysteme, und \u00fcberhaupt alle komplexen Systeme werden aus Komponenten gebaut, und \"Unterteilung\" beraubt Konstrukteure der Flexibilit\u00e4t, \"\u00dcberteilung\" der Effizienz, und falsche Grenzen der Vernunft und des seelischen Friedens. <\/p>\n<p>\n<img decoding=\"async\" alt=\"Einfaches Verantwortungsprinzip. Nicht so einfach, wie es scheint\" src=\"\/wp-content\/uploads\/2019\/06\/b70fb2b0b87cf90d41462263e839902b.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>SRP ist nicht von der Natur erfunden worden und ist kein Teil der exakten Wissenschaft. Es ergibt sich aus unseren biologischen und psychologischen Einschr\u00e4nkungen. Es ist lediglich ein Weg, komplexe Systeme mit dem menschlichen Gehirn zu steuern und zu entwickeln. Es zeigt uns, wie man ein System dekonstruiert. Die urspr\u00fcngliche Formulierung erforderte einen gewissen Grad an Telepathie, aber ich hoffe, dieser Artikel hat den Nebel ein wenig durchbrochen.<\/p>\n<p>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/454290\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>Single responsibility principle, \u043e\u043d \u0436\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0435\u0434\u0438\u043d\u043e\u0439 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438, \u043e\u043d \u0436\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0435\u0434\u0438\u043d\u043e\u0439 \u0438\u0437\u043c\u0435\u043d\u0447\u0438\u0432\u043e\u0441\u0442\u0438 \u2014 \u043a\u0440\u0430\u0439\u043d\u0435 \u0441\u043a\u043e\u043b\u044c\u0437\u043a\u0438\u0439 \u0434\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043f\u0430\u0440\u0435\u043d\u044c \u0438 \u0441\u0442\u043e\u043b\u044c \u043d\u0435\u0440\u0432\u043e\u0437\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430. \u041f\u0435\u0440\u0432\u043e\u0435 \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u043e\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 \u044d\u0442\u0438\u043c \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043b\u043e\u0441\u044c \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043a\u0443\u0440\u0441\u0430, \u043a\u043e\u0433\u0434\u0430 \u043c\u043e\u043b\u043e\u0434\u044b\u0445 \u0438 \u0437\u0435\u043b\u0435\u043d\u044b\u0445 \u043d\u0430\u0441 \u0432\u044b\u0432\u0435\u0437\u043b\u0438 \u0432 \u043b\u0435\u0441, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0437 \u043b\u0438\u0447\u0438\u043d\u043e\u043a \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u043e\u0432 \u2014 \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u043e\u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0445. [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":26229,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[702],"tags":[],"class_list":["post-34828","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/de\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47Single Responsibility Principle. \u041d\u0435 \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043a\u0430\u043a \u043a\u0430\u0436\u0435\u0442\u0441\u044f | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:00:38+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:00:38+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Single Responsibility Principle. Nicht so einfach, wie es scheint | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/de\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47Single Responsibility Principle. \u041d\u0435 \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043a\u0430\u043a \u043a\u0430\u0436\u0435\u0442\u0441\u044f | ProHoster","og:url":"https:\/\/prohoster.info\/de\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:00:38+00:00","article:modified_time":"2019-10-31T19:00:38+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"34828","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-02-09 21:46:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:14:06","updated":"2026-02-09 21:46:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/34828","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=34828"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/34828\/revisions"}],"predecessor-version":[{"id":159767,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/34828\/revisions\/159767"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/26229"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=34828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=34828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=34828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}