{"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\/fr\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya","title":{"rendered":"Principe de responsabilit\u00e9 unique. Pas si simple qu'il n'y para\u00eet","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Principe de responsabilit\u00e9 unique. Pas si simple qu&#039;il n&#039;y para\u00eet\" src=\"\/wp-content\/uploads\/2019\/06\/5b253ff55e3c97b6baf5f7a7ae7f3b98.JPG\" style=\"display:block;margin: 0 auto;\" \/> Principe de responsabilit\u00e9 unique, \u00e9galement connu sous le nom de principe de responsabilit\u00e9 unique,<br \/>\n\u00e9galement appel\u00e9 principe de variabilit\u00e9 unique \u2014 un concept difficile \u00e0 comprendre et un sujet d\u00e9licat lors d'un entretien pour un programmeur. <\/p>\n<p><\/p>\n<p>Ma premi\u00e8re rencontre s\u00e9rieuse avec ce principe a eu lieu au d\u00e9but de ma premi\u00e8re ann\u00e9e, lorsque nous, jeunes et na\u00effs, avons \u00e9t\u00e9 emmen\u00e9s dans les bois afin de transformer des larves d'\u00e9tudiants en v\u00e9ritables \u00e9tudiants.<\/p>\n<p><\/p>\n<p>Dans les bois, nous avons \u00e9t\u00e9 divis\u00e9s en groupes de 8 \u00e0 9 personnes et nous avons organis\u00e9 une comp\u00e9tition \u2014 quel groupe peut boire une bouteille de vodka le plus rapidement, sous condition que la premi\u00e8re personne dans le groupe verse la vodka dans un verre, la deuxi\u00e8me boive, et la troisi\u00e8me morde quelque chose. L'unit\u00e9 ayant termin\u00e9 son op\u00e9ration se met \u00e0 l'arri\u00e8re de la file du groupe. <\/p>\n<p><\/p>\n<p>Le cas o\u00f9 la taille de la file d'attente \u00e9tait un multiple de trois \u00e9tait une bonne r\u00e9alisation du SRP.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex> <\/p>\n<h2 id=\"opredelenie-1-edinaya-otvetstvennost\">D\u00e9finition 1. Responsabilit\u00e9 unique.<\/h2>\n<p><\/p>\n<p>La d\u00e9finition officielle du principe de responsabilit\u00e9 unique (SRP) stipule que chaque objet a sa propre responsabilit\u00e9 et une raison d'\u00eatre, et cette responsabilit\u00e9 est unique.<\/p>\n<p><\/p>\n<p>Consid\u00e9rons l'objet \u00ab Buveur \u00bb (<strong>Tippler<\/strong>).<br \/>\nPour respecter le principe SRP, nous allons diviser les responsabilit\u00e9s en trois : <\/p>\n<p><\/p>\n<ul>\n<li>L'un verse (<strong>PourOperation<\/strong>)<\/li>\n<li>L'un boit (<strong>DrinkUpOperation<\/strong>)<\/li>\n<li>L'un mord (<strong>TakeBiteOperation<\/strong>)<\/li>\n<\/ul>\n<p><\/p>\n<p>Chaque participant au processus est responsable d'un composant du processus, c'est-\u00e0-dire qu'il a une responsabilit\u00e9 atomique \u2014 boire, verser ou mordre. <\/p>\n<p><\/p>\n<p>Le Buveur, pour sa part, est un fa\u00e7ade pour ces op\u00e9rations :<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">class Tippler {\n    \/\/...\n    void Act(){\n        _pourOperation.Do() \/\/ verser\n        _drinkUpOperation.Do() \/\/ boire\n        _takeBiteOperation.Do() \/\/ mordre\n    }\n}<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Principe de responsabilit\u00e9 unique. Pas si simple qu&#039;il n&#039;y para\u00eet\" src=\"\/wp-content\/uploads\/2019\/06\/8d591a474e3555edfee3ffebc28d079b.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h4 id=\"zachem\">Pourquoi ?<\/h4>\n<p><\/p>\n<p>Un programmeur \u00e9crit du code pour un homme-singe, et l'homme-singe est inattentif, stupide et toujours press\u00e9. Il peut retenir et comprendre environ 3 \u00e0 7 termes \u00e0 la fois.<br \/>\nDans le cas du Buveur, il y a trois termes. Cependant, si nous \u00e9crivons du code sous forme de feuille unique, celui-ci comportera des bras, des verres, des coups de poing et des d\u00e9bats infinis sur la politique. Et tout cela se trouvera dans le corps d'une seule m\u00e9thode. Je suis s\u00fbr \u2014 vous avez d\u00e9j\u00e0 vu ce type de code dans votre pratique. Ce n'est pas le plus humain des d\u00e9fis pour la psych\u00e9.<\/p>\n<p><\/p>\n<p>D'un autre c\u00f4t\u00e9, l'homme-sing\u00e9 est con\u00e7u pour mod\u00e9liser des objets du monde r\u00e9el dans sa t\u00eate. Dans son imagination, il peut les heurter, les assembler pour cr\u00e9er de nouveaux objets et tout aussi bien les d\u00e9monter. Imaginez un ancien mod\u00e8le de voiture. Vous pouvez imaginer ouvrir la porte, d\u00e9visser le rev\u00eatement et voir l\u00e0-dedans les m\u00e9canismes des fen\u00eatres, avec des engrenages \u00e0 l'int\u00e9rieur. Mais vous ne pouvez pas voir tous les composants de la voiture en m\u00eame temps, dans un \u00ab listing \u00bb. Du moins l'\u00ab homme-sing\u00e9 \u00bb ne peut pas.<\/p>\n<p><\/p>\n<p>C'est pourquoi les programmeurs d\u00e9composent des m\u00e9canismes complexes en un ensemble d'\u00e9l\u00e9ments moins complexes et fonctionnels. Cependant, il existe diff\u00e9rentes mani\u00e8res de d\u00e9composer : dans de nombreuses anciennes voitures, le conduit d'air sort dans la porte, alors que dans les modernes, une d\u00e9faillance de l'\u00e9lectronique de la serrure emp\u00eache le moteur de d\u00e9marrer, ce qui complique les r\u00e9parations.<\/p>\n<p><\/p>\n<p>Eh bien, <strong>SRP \u2014 est un principe qui explique COMMENT d\u00e9composer, c'est-\u00e0-dire o\u00f9 tracer la ligne de s\u00e9paration.<\/strong>. <\/p>\n<p><\/p>\n<p>Il dit qu'il faut d\u00e9composer selon le principe de s\u00e9paration \u00ab des responsabilit\u00e9s \u00bb, c\u2019est-\u00e0-dire par les t\u00e2ches des diff\u00e9rents objets.<\/p>\n<p>\n<img decoding=\"async\" alt=\"Principe de responsabilit\u00e9 unique. Pas si simple qu&#039;il n&#039;y para\u00eet\" src=\"\/wp-content\/uploads\/2019\/06\/b1980c3dc9742b921eb818f14fe3527e.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Revenons \u00e0 l'ivrogne et aux avantages que l'homme-singe obtient en d\u00e9composant : <\/p>\n<p><\/p>\n<ul>\n<li>Le code est devenu extr\u00eamement clair \u00e0 chaque niveau.<\/li>\n<li>Le code peut \u00eatre \u00e9crit par plusieurs programmeurs en m\u00eame temps (chacun \u00e9crivant un \u00e9l\u00e9ment distinct).<\/li>\n<li>Les tests automatis\u00e9s sont simplifi\u00e9s \u2014 plus un \u00e9l\u00e9ment est simple, plus il est facile \u00e0 tester.<\/li>\n<li>Une composition de code appara\u00eet \u2014 on peut remplacer. <strong>DrinkUpOperation<\/strong> par une op\u00e9ration o\u00f9 l'ivrogne verse un liquide sous la table. Ou remplacer l'op\u00e9ration de versement par une op\u00e9ration o\u00f9 vous m\u00e9langez du vin et de l'eau ou de la vodka et de la bi\u00e8re. Selon les exigences de l'entreprise, vous pouvez tout faire, tout en ne touchant pas au code de la m\u00e9thode. <strong>Tippler.Act<\/strong>. <\/li>\n<li>\u00c0 partir de ces op\u00e9rations, vous pouvez construire un glouton (en utilisant uniquement. <strong>TakeBitOperation<\/strong>), un alcoolique (en utilisant uniquement. <strong>DrinkUpOperation<\/strong> directement de la bouteille) et satisfaire de nombreuses autres exigences commerciales.<\/li>\n<\/ul>\n<p><\/p>\n<p><em>(Oh, il semble que ce soit d\u00e9j\u00e0 le principe OCP, et j'ai viol\u00e9 la responsabilit\u00e9 de ce post.) <\/em><\/p>\n<p><\/p>\n<p>Et bien s\u00fbr, les inconv\u00e9nients : <\/p>\n<p><\/p>\n<ul>\n<li>Il faudra cr\u00e9er plus de types. <\/li>\n<li>L'ivrogne boira pour la premi\u00e8re fois quelques heures plus tard qu'il ne le pourrait.<\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"opredelenie-2-edinaya-izmenchivost\">D\u00e9finition 2. Variabilit\u00e9 unique.<\/h2>\n<p><\/p>\n<p>Permettez-moi, mesdames et messieurs ! La classe du buveur a \u00e9galement une responsabilit\u00e9 unique \u2014 il boit ! Et de toute fa\u00e7on, le mot \u00ab responsabilit\u00e9 \u00bb est un concept extr\u00eamement flou. Quelqu'un est responsable du sort de l'humanit\u00e9, et quelqu'un d'autre est responsable de relever les pingouins renvers\u00e9s au p\u00f4le.<\/p>\n<p><\/p>\n<p>Consid\u00e9rons deux impl\u00e9mentations du buveur. La premi\u00e8re, mentionn\u00e9e ci-dessus, contient trois classes : verser, boire et grignoter.<\/p>\n<p><\/p>\n<p>La seconde, \u00e9crite selon la m\u00e9thodologie \u00ab En avant et seulement en avant \u00bb et contient toute la logique dans la m\u00e9thode <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>Ces deux classes, du point de vue d'un observateur ext\u00e9rieur, semblent absolument identiques et accomplissent une seule responsabilit\u00e9, celle de \u00ab boire \u00bb. <\/p>\n<p><\/p>\n<p>Quelle honte !<\/p>\n<p><\/p>\n<p>Nous nous tournons alors sur Internet et d\u00e9couvrons une autre d\u00e9finition du SRP \u2013 le Principe de Changeabilit\u00e9 Unique (Single Changeability Principle).<\/p>\n<p><\/p>\n<p>Le SCP stipule que \u00ab<strong>Un module n\u2019a qu\u2019un seul et unique motif de changement<\/strong>\u00ab . C'est-\u00e0-dire que \u00ab La responsabilit\u00e9 est un motif de changement \u00bb. <\/p>\n<p><\/p>\n<p><em>(On dirait que les gars qui ont invent\u00e9 la d\u00e9finition originale croyaient aux capacit\u00e9s t\u00e9l\u00e9pathiques de l\u2019homme-singe)<\/em><\/p>\n<p><\/p>\n<p>Maintenant tout devient clair. On peut modifier s\u00e9par\u00e9ment les proc\u00e9dures de versement, de consommation et de grignotage, et dans le buveur lui-m\u00eame, on ne peut changer que l'ordre et la composition des op\u00e9rations, par exemple, en d\u00e9pla\u00e7ant le grignotage avant de boire ou en ajoutant la lecture d'un toast.<\/p>\n<p><\/p>\n<p>Dans l'approche \u00ab En avant et seulement en avant \u00bb, tout ce qui peut \u00eatre chang\u00e9 ne change que dans la m\u00e9thode. <strong>Act<\/strong>. C'est peut-\u00eatre lisible et efficace lorsqu'il y a peu de logique et qu'elle change rarement, mais cela finit souvent par des m\u00e9thodes horribles de 500 lignes chacune, avec un nombre de if sup\u00e9rieur \u00e0 ce qui est n\u00e9cessaire pour l'adh\u00e9sion de la Russie \u00e0 l\u2019OTAN. <\/p>\n<p><\/p>\n<h2 id=\"opredelenie-3-lokalizaciya-izmeneniy\">D\u00e9finition 3. Localisation des changements.<\/h2>\n<p><\/p>\n<p>Les buveurs ne comprennent souvent pas pourquoi ils se r\u00e9veillent dans un appartement qui n\u2019est pas le leur, ou o\u00f9 se trouve leur t\u00e9l\u00e9phone portable. Il est temps d'ajouter une journalisation d\u00e9taill\u00e9e.<\/p>\n<p><\/p>\n<p>Commencez la journalisation avec le processus de versement :<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">class PourOperation: IOperation{\n    PourOperation(ILogger log \/*....*\/){\/*...*\/}\n    \/\/...\n    void Do(){\n        _log.Log($\"Avant de verser avec {_hand} et {_bottle}\");\n        \/\/ Logique m\u00e9tier de versement ...\n        _log.Log($\"Apr\u00e8s avoir vers\u00e9 avec {_hand} et {_bottle}\");\n    }\n}<\/code><\/pre>\n<p><\/p>\n<p>en l'encapsulant dans <strong>PourOperation<\/strong>, nous avons agi avec sagesse en termes de responsabilit\u00e9 et d'encapsulation, mais nous rencontrons maintenant un dilemme avec le principe de variabilit\u00e9. En plus de l'op\u00e9ration elle-m\u00eame, qui peut changer, la journalisation devient \u00e9galement variable. Nous devrons s\u00e9parer et cr\u00e9er un journaliseur sp\u00e9cial pour l'op\u00e9ration de versement :<\/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             \/\/... logique m\u00e9tier\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>Le lecteur attentif remarquera que <strong>LogAfter<\/strong>, <strong>LogBefore<\/strong> et <strong>OnError<\/strong> peuvent \u00e9galement changer ind\u00e9pendamment, et \u00e0 l'instar des actions pr\u00e9c\u00e9dentes, cela cr\u00e9era trois classes : <strong>PourLoggerBefore<\/strong>, <strong>PourLoggerAfter<\/strong> et <strong>PourErrorLogger<\/strong>.<\/p>\n<p><\/p>\n<p>Et en se rappelant qu'il y a trois op\u00e9rations pour le verseur, nous obtenons neuf classes de journalisation. Au total, le verseur consiste en 14 (!!!) classes.<\/p>\n<p><\/p>\n<p>Hyperbole ? \u00c0 peine ! Un homme-singe avec une grenade de d\u00e9composition r\u00e9duira le \u201cverseur\u201d en carafe, verre, op\u00e9rateurs de versement, service d'eau, mod\u00e8le physique de collision des mol\u00e9cules, et le prochain trimestre tentera de d\u00e9m\u00ealer les d\u00e9pendances sans variables globales. Et croyez-moi \u2014 il ne s'arr\u00eatera pas.<\/p>\n<p><\/p>\n<p>C'est \u00e0 ce moment-l\u00e0 que beaucoup arrivent \u00e0 la conclusion que le SRP est des contes des royaumes roses, et ils se mettent \u00e0 raconter des histoires\u2026<\/p>\n<p><\/p>\n<p>... sans jamais apprendre l'existence de la troisi\u00e8me d\u00e9finition du SRP : <\/p>\n<p><\/p>\n<p>\u00ab Le principe de responsabilit\u00e9 unique dit que <strong>les choses semblables \u00e0 modifier doivent \u00eatre conserv\u00e9es au m\u00eame endroit<\/strong>\u00ab . ou \u00ab<strong>Ce qui change ensemble doit \u00eatre conserv\u00e9 au m\u00eame endroit<\/strong>\u201d<\/p>\n<p><\/p>\n<p>C'est-\u00e0-dire que si nous changeons la journalisation de l'op\u00e9ration, nous devons le faire au m\u00eame endroit.<\/p>\n<p><\/p>\n<p>C'est un point tr\u00e8s important \u2014 car toutes les explications du SRP qui ont \u00e9t\u00e9 donn\u00e9es ci-dessus disaient qu'il fallait fragmenter les types tant qu'ils peuvent \u00eatre fragment\u00e9s, ce qui imposait une \u00ab limite sup\u00e9rieure \u00bb sur la taille de l'objet, et maintenant nous parlons aussi d'une \u00ab limite inf\u00e9rieure \u00bb. En d'autres termes, <strong>Le SRP exige non seulement de \u00ab fragmenter tant que \u00e7a se fracture \u00bb, mais aussi de ne pas en faire trop \u2014 \u00ab ne pas fragmenter les choses li\u00e9es \u00bb.<\/strong>. C'est une grande bataille entre le rasoir d'Occam et l'homme-singe !<\/p>\n<p>\n<img decoding=\"async\" alt=\"Principe de responsabilit\u00e9 unique. Pas si simple qu&#039;il n&#039;y para\u00eet\" src=\"\/wp-content\/uploads\/2019\/06\/2e349a5b119a511d716341f3f6725844.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Maintenant, le verseur devrait trouver cela plus facile. En plus de ne pas avoir \u00e0 d\u00e9composer le IPourLogger en trois classes, nous pouvons \u00e9galement combiner tous les journaliseurs en un seul type :<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">class OperationLogger{\n    public OperationLogger(string operationName){\n\/*..*\/}\n    public void LogBefore(object[] args){\n\/*...*\/}\n    public void LogAfter(object[] args){\n\/*..*\/}\n    public void LogError(object[] args, exception e){\n\/*..*\/}\n}<\/code><\/pre>\n<p><\/p>\n<p>Et si un quatri\u00e8me type d'op\u00e9ration venait s'ajouter, la journalisation serait d\u00e9j\u00e0 pr\u00eate pour cela. Le code des op\u00e9rations elles-m\u00eames est propre et d\u00e9barrass\u00e9 de bruit infrastructurel.<\/p>\n<p><\/p>\n<p>Nous avons donc 5 classes pour r\u00e9soudre la t\u00e2che de la consommation :<\/p>\n<p><\/p>\n<ul>\n<li>Op\u00e9ration de versement<\/li>\n<li>Op\u00e9ration de consommation<\/li>\n<li>Op\u00e9ration d'accompagnement<\/li>\n<li>Journaliseur<\/li>\n<li>Facade de consommation<\/li>\n<\/ul>\n<p><\/p>\n<p>Chacune d'entre elles est strictement responsable d'une seule fonctionnalit\u00e9, ayant une seule raison de changement. Toutes les r\u00e8gles similaires pour le changement sont regroup\u00e9es. <\/p>\n<p>\n<b class=\"spoiler_title\">Exemple de la vie r\u00e9elle<\/b><\/p>\n<p>Un jour, nous avons d\u00e9velopp\u00e9 un service d'enregistrement automatique pour un client B2B. Et un GOD-m\u00e9thode de 200 lignes est apparue avec un contenu similaire :<\/p>\n<p><\/p>\n<ul>\n<li>Va dans 1C et cr\u00e9e un compte<\/li>\n<li>Avec ce compte, rends-toi au module de paiement et cr\u00e9e-le l\u00e0-bas<\/li>\n<li>V\u00e9rifie qu'aucun compte avec ce num\u00e9ro n'est cr\u00e9\u00e9 dans le principal <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/fr\/server\/dts-dronten\/\"   title=\"le serveur\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"2485\">le serveur<\/a><\/li>\n<li>Cr\u00e9e un nouveau compte<\/li>\n<li>Ajoute le r\u00e9sultat de l'enregistrement dans le module de paiement et le num\u00e9ro 1C au service des r\u00e9sultats d'enregistrement<\/li>\n<li>Ajoute les informations du compte dans ce tableau<\/li>\n<li>Cr\u00e9e un num\u00e9ro de point pour ce client dans le service des points. Passe le num\u00e9ro de compte 1C \u00e0 ce service.<\/li>\n<\/ul>\n<p><\/p>\n<p>Et il y avait environ 10 autres op\u00e9rations commerciales dans cette liste avec une interconnexion terrible. L'objet compte \u00e9tait n\u00e9cessaire presque \u00e0 tous. L'identifiant du point et le nom du client \u00e9taient n\u00e9cessaires dans la moiti\u00e9 des appels.<\/p>\n<p><\/p>\n<p>Apr\u00e8s une heure de refactorisation, nous avons pu s\u00e9parer le code d'infrastructure et certains d\u00e9tails du travail avec le compte en m\u00e9thodes\/classes distinctes. La m\u00e9thode God a \u00e9t\u00e9 all\u00e9g\u00e9e, mais il restait 100 lignes de code qui ne voulaient pas se d\u00e9m\u00ealer. <\/p>\n<p><\/p>\n<p>Ce n'est que quelques jours plus tard que j'ai compris que l'essence de cette m\u00e9thode \u00ab all\u00e9g\u00e9e \u00bb est en fait un algorithme commercial. Et que la description initiale du cahier des charges \u00e9tait assez complexe. Et que la tentative de d\u00e9couper cette m\u00e9thode serait une violation du SRP, et non le contraire. <\/p>\n<p><\/p>\n<h2 id=\"formalizm\">Formalisme.<\/h2>\n<p><\/p>\n<p>Il est temps de laisser notre consommateur tranquille. Essuie tes larmes \u2014 nous reviendrons \u00e0 lui un jour. Pour l'instant, formalisons les connaissances de cet article. <\/p>\n<p><\/p>\n<h4 id=\"formalizm-1-opredelenie-srp\">Formalisme 1. D\u00e9finition du SRP<\/h4>\n<p><\/p>\n<ol>\n<li>S\u00e9parez les \u00e9l\u00e9ments de sorte que chacun d'eux soit responsable de quelque chose de unique.<\/li>\n<li>La responsabilit\u00e9 se d\u00e9chiffre comme \u00ab motif de changement \u00bb. Cela signifie que chaque \u00e9l\u00e9ment n'a qu'un seul motif de changement, en termes de logique commerciale.<\/li>\n<li>Les \u00e9ventuels changements de logique commerciale doivent \u00eatre localis\u00e9s. Les \u00e9l\u00e9ments modifiables synchroniquement doivent \u00eatre \u00e0 proximit\u00e9.<\/li>\n<\/ol>\n<p><\/p>\n<h4 id=\"formalizm-2-neobhodimye-kriterii-samoproverki\">Formalisme 2. Crit\u00e8res n\u00e9cessaires pour l'auto-\u00e9valuation.<\/h4>\n<p><\/p>\n<p>Je n'ai pas trouv\u00e9 de crit\u00e8res suffisants pour la r\u00e9alisation du SRP. Mais il y a des conditions n\u00e9cessaires :<\/p>\n<p><\/p>\n<p>1) Posez-vous la question : que fait cette classe\/m\u00e9thode\/module\/service ? Vous devez y r\u00e9pondre par une d\u00e9finition simple. (merci <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\">explications<\/b><\/p>\n<p>Cependant, parfois, trouver une d\u00e9finition simple est tr\u00e8s difficile. <\/p>\n<p><\/p>\n<p>2) La correction d'un bug ou l'ajout d'une nouvelle fonctionnalit\u00e9 touche le minimum de fichiers\/classes. Id\u00e9alement \u2014 un seul. <\/p>\n<p>\n<b class=\"spoiler_title\">explications<\/b><\/p>\n<p>Comme la responsabilit\u00e9 (pour la fonctionnalit\u00e9 ou le bug) est encapsul\u00e9e dans un fichier\/classe, vous savez exactement o\u00f9 chercher et quoi modifier. Par exemple : la fonctionnalit\u00e9 de modification de l'affichage des op\u00e9rations de journalisation ne n\u00e9cessitera de changer que le syst\u00e8me de journalisation. Il n'est pas n\u00e9cessaire de fouiller dans tout le reste du code. <\/p>\n<p><\/p>\n<p>Un autre exemple \u2014 l'ajout d'un nouveau contr\u00f4le UI, similaire aux pr\u00e9c\u00e9dents. Si cela vous oblige \u00e0 ajouter 10 entit\u00e9s diff\u00e9rentes et 15 convertisseurs diff\u00e9rents \u2014 il semble que vous ayez \"d\u00e9rap\u00e9\".<\/p>\n<p><\/p>\n<p>3) Si plusieurs d\u00e9veloppeurs travaillent sur diff\u00e9rentes fonctionnalit\u00e9s de votre projet, la probabilit\u00e9 de conflit de fusion, c'est-\u00e0-dire la probabilit\u00e9 que le m\u00eame fichier\/classe soit modifi\u00e9 par plusieurs d\u00e9veloppeurs en m\u00eame temps, est minimale.<\/p>\n<p>\n<b class=\"spoiler_title\">explications<\/b><\/p>\n<p>Si, en ajoutant la nouvelle op\u00e9ration \u00ab Verser de la vodka sous la table \u00bb, vous devez toucher le logger, l'op\u00e9ration de boisson et de versement \u2014 cela semble indiquer que les responsabilit\u00e9s sont mal r\u00e9parties. Bien s\u00fbr, ce n'est pas toujours possible, mais il est important d'essayer de r\u00e9duire cet indicateur. <\/p>\n<p><\/p>\n<p>4) Lors d'une question de clarification sur la logique commerciale (d'un d\u00e9veloppeur ou d'un manager), vous ne devez interroger qu'une seule classe\/fichier et obtenir l'information uniquement de l\u00e0.<\/p>\n<p>\n<b class=\"spoiler_title\">explications<\/b><\/p>\n<p>Les fonctionnalit\u00e9s, r\u00e8gles ou algorithmes sont \u00e9crits compactement, chacun \u00e0 un seul endroit, et non \u00e9parpill\u00e9s en drapeaux dans tout le code.<\/p>\n<p><\/p>\n<p>5) Le nommage est clair.<\/p>\n<p>\n<b class=\"spoiler_title\">explications<\/b><\/p>\n<p>Notre classe ou m\u00e9thode est responsable d'une seule chose, et cette responsabilit\u00e9 se refl\u00e8te dans son nom.<\/p>\n<p><\/p>\n<p>AllManagersManagerService \u2014 tr\u00e8s probablement une classe God.<br \/>\nLocalPayment \u2014 probablement non. <\/p>\n<p><\/p>\n<h4 id=\"formalizm-3-metodika-razrabotki-okkama-first\">Formalism 3. M\u00e9thodologie de d\u00e9veloppement \u00ab Ockham-first \u00bb.<\/h4>\n<p><\/p>\n<p>Au d\u00e9but de la conception, le monkey-man ne conna\u00eet pas et ne ressent pas toutes les subtilit\u00e9s de la t\u00e2che \u00e0 r\u00e9soudre et peut faire des erreurs. On peut se tromper de diff\u00e9rentes mani\u00e8res :<\/p>\n<p><\/p>\n<ul>\n<li>Cr\u00e9er des objets trop grands en fusionnant diff\u00e9rentes responsabilit\u00e9s<\/li>\n<li>D\u00e9composer en divisant une seule responsabilit\u00e9 en plusieurs types diff\u00e9rents<\/li>\n<li>D\u00e9finir incorrectement les limites de responsabilit\u00e9<\/li>\n<\/ul>\n<p><\/p>\n<p>Il est important de se souvenir de la r\u00e8gle : \u00ab il vaut mieux se tromper en faveur du surplus \u00bb, ou \u00ab si vous n'\u00eates pas s\u00fbr \u2014 ne divisez pas \u00bb. Par exemple, si votre classe regroupe deux responsabilit\u00e9s, elle reste compr\u00e9hensible et peut \u00eatre divis\u00e9e en deux avec un minimum de modifications du code client. Reconstituer un verre \u00e0 partir de morceaux de verre est g\u00e9n\u00e9ralement plus difficile en raison du contexte dispers\u00e9 dans plusieurs fichiers et de l'absence des d\u00e9pendances n\u00e9cessaires dans le code client. <\/p>\n<p><\/p>\n<h2 id=\"pora-zakruglyatsya\">Il est temps de conclure<\/h2>\n<p><\/p>\n<p>Le domaine d'application du SRP ne se limite pas \u00e0 la POO et au SOLID. Il s'applique aux m\u00e9thodes, fonctions, classes, modules, microservices et services. Il est applicable aussi bien au d\u00e9veloppement \u00ab figaks-figaks-et-en-prod \u00bb qu\u2019au d\u00e9veloppement \u00ab rocket-science \u00bb, rendant partout le monde un peu meilleur. Si l'on y r\u00e9fl\u00e9chit, c\u2019est sans doute un principe fondamental de toute ing\u00e9nierie. La m\u00e9canique, les syst\u00e8mes de contr\u00f4le et, en g\u00e9n\u00e9ral, tous les syst\u00e8mes complexes sont construits \u00e0 partir de composants, et le \u00ab manque de d\u00e9composition \u00bb prive les concepteurs de flexibilit\u00e9, tandis que \u00ab trop de d\u00e9composition \u00bb menace l\u2019efficacit\u00e9, et des limites incorrectes compromettent la rationalit\u00e9 et la tranquillit\u00e9 d'esprit. <\/p>\n<p>\n<img decoding=\"async\" alt=\"Principe de responsabilit\u00e9 unique. Pas si simple qu&#039;il n&#039;y para\u00eet\" src=\"\/wp-content\/uploads\/2019\/06\/b70fb2b0b87cf90d41462263e839902b.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Le SRP n'est pas une invention de la nature et ne fait pas partie des sciences exactes. Il \u00e9mane de nos propres limites biologiques et psychologiques. C'est juste un moyen de contr\u00f4ler et de d\u00e9velopper des syst\u00e8mes complexes \u00e0 l'aide du cerveau humain-primat. Il nous indique comment d\u00e9composer un syst\u00e8me. La formulation initiale n\u00e9cessitait une certaine comp\u00e9tence en t\u00e9l\u00e9pathie, mais j'esp\u00e8re que cet article a un peu lev\u00e9 le brouillard.<\/p>\n<p>Source : <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.2.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\/fr\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\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\/fr\/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\udd47Principe de Responsabilit\u00e9 Unique. Pas aussi simple qu'il n'y para\u00eet | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","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\/fr\/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\/fr\/wp-json\/wp\/v2\/posts\/34828","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=34828"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/34828\/revisions"}],"predecessor-version":[{"id":159767,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/34828\/revisions\/159767"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/26229"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=34828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=34828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=34828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}