Il semble assez clair que "Principe de responsabilité unique" ne signifie pas "une seule chose". Voilà à quoi servent les méthodes.
public Interface CustomerCRUD
{
public void Create(Customer customer);
public Customer Read(int CustomerID);
public void Update(Customer customer);
public void Delete(int CustomerID);
}
Bob Martin dit que "les classes ne devraient avoir qu'une seule raison de changer". Mais c’est difficile de garder l’esprit au clair si vous êtes un nouveau programmeur chez SOLID.
J'ai écrit une réponse à une autre question , dans laquelle je suggérais que les responsabilités ressemblaient à des titres d'emploi, et j'ai dansé autour du sujet en utilisant une métaphore de restaurant pour illustrer mon propos. Mais cela n'énonce toujours pas un ensemble de principes que quelqu'un pourrait utiliser pour définir les responsabilités de leurs classes.
Alors, comment fais-tu? Comment déterminez-vous les responsabilités que chaque classe devrait avoir et comment définissez-vous une responsabilité dans le contexte du PÉR?
la source
Réponses:
Une façon de comprendre cela consiste à imaginer des modifications potentielles des exigences dans les projets futurs et à vous demander ce que vous devrez faire pour les réaliser.
Par exemple:
Ou:
L'idée est de minimiser l'empreinte des modifications potentielles futures, en limitant les modifications de code à une zone de code par zone de modification.
Au minimum, vos cours doivent séparer les préoccupations logiques des préoccupations physiques. Un grand ensemble d'exemples se trouvent dans l'
System.IO
espace de noms: là , nous pouvons trouver un divers types de flux physiques (par exempleFileStream
,MemoryStream
ouNetworkStream
) et divers lecteurs et écrivains (BinaryWriter
,TextWriter
) qui travaillent à un niveau logique. En les séparant de cette façon, nous évitons l' explosion combinatoires: au lieu d' avoir besoinFileStreamTextWriter
,FileStreamBinaryWriter
,NetworkStreamTextWriter
,NetworkStreamBinaryWriter
,MemoryStreamTextWriter
etMemoryStreamBinaryWriter
, vous venez de brancher l'écrivain et le flux et vous pouvez avoir ce que vous voulez. Ensuite, nous pouvons ajouter par exemple unXmlWriter
, sans avoir à le réimplémenter séparément pour la mémoire, les fichiers et le réseau.la source
Sur le plan pratique, les responsabilités sont limitées par les éléments susceptibles de changer. Ainsi, il n’existe malheureusement pas de méthode scientifique ou théorique pour arriver à ce qui constitue une responsabilité. C'est un jugement.
Il est sur ce qui, dans votre expérience , est susceptible de changer.
Nous avons tendance à appliquer le langage du principe dans une rage hyperbolique, littérale et zélée. Nous avons tendance à diviser les classes parce qu'elles peuvent changer ou selon des lignes qui nous aident simplement à résoudre les problèmes. (Cette dernière raison n'est pas intrinsèquement mauvaise.) Mais, le SRP n'existe pas pour lui-même; il est au service de la création de logiciels maintenables.
Encore une fois, si les divisions ne sont pas motivées par des changements probables , elles ne sont pas vraiment au service du PÉR 1, si YAGNI est plus applicable. Les deux servent le même objectif ultime. Et les deux sont des questions de jugement - espérons un jugement expérimenté .
Lorsque Oncle Bob écrit à ce sujet, il suggère de penser à la "responsabilité" en termes de "qui demande le changement". En d'autres termes, nous ne voulons pas que le parti A perde son emploi, car le parti B a demandé un changement.
Les développeurs bons et expérimentés auront une idée des changements probables. Et cette liste mentale variera quelque peu selon l'industrie et l'organisation.
Ce qui constitue une responsabilité dans votre application particulière, au sein de votre organisation particulière, est finalement une question de jugement expérimenté . Il s'agit de ce qui est susceptible de changer. Et, dans un sens, il s'agit de savoir à qui appartient la logique interne du module.
1. Pour être clair, cela ne signifie pas que ce sont de mauvaises divisions. Ce pourraient être de grandes divisions qui améliorent considérablement la lisibilité du code. Cela signifie simplement qu'ils ne sont pas motivés par le PÉR.
la source
Je suis "les cours ne devraient avoir qu'une seule raison de changer".
Pour moi, cela signifie de penser à des projets compliqués que mon propriétaire de produit pourrait proposer ("Nous devons prendre en charge le mobile!", "Nous devons accéder au cloud!", "Nous devons prendre en charge le chinois!"). De bonnes conceptions limiteront l’impact de ces projets sur de plus petites zones et les rendront relativement faciles à réaliser. De mauvaises conceptions impliquent d'utiliser beaucoup de code et de procéder à de nombreuses modifications risquées.
L’expérience est la seule chose que j’ai trouvée pour bien évaluer la probabilité de ces stratagèmes délirants - car faciliter l’un des deux, en rendre deux autres plus difficiles - et évaluer la qualité d’une conception. Les programmeurs expérimentés peuvent imaginer ce qu'ils devraient faire pour changer le code, ce qui traîne pour les mordre dans le cul, et quelles astuces facilitent les choses. Les programmeurs expérimentés ont un bon pressentiment à quel point ils sont foutus lorsque le responsable du produit leur demande des trucs fous.
Pratiquement, je trouve que les tests unitaires aident ici. Si votre code est inflexible, il sera difficile à tester. Si vous ne pouvez pas injecter de simulacres ou d'autres données de test, vous ne pourrez probablement pas injecter ce
SupportChinese
code.Une autre mesure approximative est le pas d'ascenseur. Les ascenseurs traditionnels sont "si vous étiez dans un ascenseur avec un investisseur, pouvez-vous lui vendre une idée?". Les entreprises en démarrage doivent avoir une description simple et succincte de leurs activités - de leurs priorités. De même, les classes (et les fonctions) doivent avoir une description simple de ce qu’elles font . Non "cette classe implémente certains fubar tels que vous pouvez les utiliser dans ces scénarios spécifiques". Vous pouvez dire quelque chose à un autre développeur: "Cette classe crée des utilisateurs". Si vous ne pouvez pas communiquer cela aux autres développeurs, vous allez avoir des bogues.
la source
Personne ne sait. Ou du moins, nous ne pouvons pas nous mettre d’accord sur une définition. C’est ce qui rend SPR (et d’autres principes SOLID) assez controversé.
Je dirais que pouvoir comprendre ce qui est ou non une responsabilité est l’une des compétences que le développeur de logiciels doit acquérir au cours de sa carrière. Plus vous écrivez et révisez de code, plus vous aurez d’expérience pour déterminer s’il s’agit d’une responsabilité unique ou à responsabilités multiples. Ou si la responsabilité unique est fractionnée entre différentes parties du code.
Je dirais que l’objectif principal du SRP n’est pas d’être une règle stricte. C'est pour nous rappeler de veiller à la cohésion dans le code et de toujours faire un effort conscient pour déterminer quel code est cohérent et ce qui ne l'est pas.
la source
Je pense que le terme "responsabilité" est utile en tant que métaphore, car il nous permet d'utiliser le logiciel pour déterminer dans quelle mesure le logiciel est organisé. En particulier, je me concentrerais sur deux principes:
Ces deux principes nous ont permis de nous décharger de nos responsabilités, car ils se jouent mutuellement. Si vous autorisez un élément de code à faire quelque chose pour vous, il doit être responsable de ce qu'il fait. Cela entraîne la responsabilité d'une classe qui pourrait devoir grandir, élargissant c'est "une raison de changer" à des domaines de plus en plus larges. Cependant, à mesure que vous élargissez les choses, vous commencez naturellement à vous retrouver dans des situations où plusieurs entités sont responsables de la même chose. Cela soulève de nombreux problèmes de responsabilité dans la vie réelle, donc c’est sûrement un problème de codage. En conséquence, ce principe entraîne la réduction des portées lorsque vous divisez la responsabilité en parcelles non dupliquées.
Outre ces deux principes, un troisième principe semble raisonnable:
Considérez un programme fraichement mis à jour… une ardoise vierge. Au début, vous n'avez qu'une seule entité, le programme dans son ensemble. Il est responsable de ... tout. Naturellement, à un moment donné, vous commencerez à déléguer des responsabilités à des fonctions ou à des classes. À ce stade, les deux premières règles entrent en jeu, vous obligeant à équilibrer cette responsabilité. Le programme de niveau supérieur est toujours responsable de la production globale, tout comme un responsable est responsable de la productivité de son équipe, mais chaque sous-entité se voit déléguer la responsabilité, ce qui lui donne le pouvoir de s’acquitter de cette responsabilité.
En prime, cela rend SOLID particulièrement compatible avec tous les développements de logiciels d'entreprise nécessaires. Toutes les entreprises de la planète ont une idée de la manière de déléguer des responsabilités, et elles ne sont pas toutes d'accord. Si vous déléguez des responsabilités dans votre logiciel d'une manière qui rappelle la délégation de votre entreprise, il sera beaucoup plus facile pour les futurs développeurs de se familiariser avec la façon dont vous faites les choses dans cette entreprise.
la source
Oncle Bob donne cet exemple amusant dans cette conférence à Yale :
Il dit que cela
Employee
a trois raisons de changer, trois sources d'exigences de changement, et donne cette explication amusante et ironique , mais illustrative néanmoins:Il donne cette solution qui résout la violation de SRP, mais doit encore résoudre la violation de DIP qui n'est pas montrée dans la vidéo.
la source
Je pense qu'un meilleur moyen de subdiviser les choses que les "raisons de changer" est de commencer par se demander s'il serait logique d'exiger que le code qui doit effectuer deux actions (ou plus) ait besoin de contenir une référence d'objet distincte. pour chaque action, et s'il serait utile d'avoir un objet public pouvant effectuer une action mais pas l'autre.
Si les réponses aux deux questions sont oui, cela suggérerait que les actions devraient être effectuées par des classes séparées. Si les réponses aux deux questions sont non, cela suggérerait que du point de vue public, il devrait y avoir une classe; si le code utilisé est difficile à manier, il peut être subdivisé en classe interne en classes privées. Si la réponse à la première question est non, mais que la seconde soit oui, il devrait exister une classe distincte pour chaque action, ainsi qu'une classe composite incluant des références aux instances des autres.
Si vous avez des classes distinctes pour le clavier, le bip, la lecture numérique, l’imprimante et le tiroir-caisse d’une caisse, et aucune classe composite pour une caisse enregistreuse complète, le code censé traiter une transaction peut finir par être invoqué accidentellement dans une Ce mode prend les entrées du clavier d’une machine, produit du bruit provenant du bip de la deuxième machine, affiche les chiffres sur l’affichage de la troisième machine, imprime un reçu sur l’imprimante d’une quatrième machine et ouvre le cinquième tiroir-caisse. Chacune de ces sous-fonctions pourrait être utilement gérée par une classe séparée, mais il devrait également y avoir une classe composite qui les associe. La classe composite doit déléguer autant de logique que possible aux classes constituantes,
On pourrait dire que la "responsabilité" de chaque classe consiste soit à intégrer une logique réelle, soit à fournir un point d'attachement commun à plusieurs autres classes qui le font, mais il est important de se concentrer avant tout sur la manière dont le code client doit afficher une classe. S'il est logique que le code client voie quelque chose comme un seul objet, alors le code client doit le voir comme un seul objet.
la source
SRP est difficile à obtenir. Il s’agit principalement d’attribuer des "emplois" à votre code et de s’assurer que chaque partie a des responsabilités claires. Comme dans la vie réelle, dans certains cas, le partage du travail entre personnes peut s’avérer tout à fait naturel, mais dans d’autres cas, il peut s'avérer très délicat, surtout si vous ne le connaissez pas (ou le travail).
Je te recommande toujours juste écrire du code simple qui fonctionne en premier lieu , puis de le refactoriser un peu: vous aurez tendance à voir comment le code se met naturellement à se regrouper après un certain temps. Je pense que c'est une erreur de forcer les responsabilités avant de connaître le code (ou les personnes) et le travail à effectuer.
Une chose que vous remarquerez est que le module commence à en faire trop et qu’il est difficile à déboguer / maintenir. C'est le moment de refacturer; Quel devrait être le travail principal et quelles tâches pourraient être confiées à un autre module? Par exemple, doit-il gérer les contrôles de sécurité et les autres tâches, ou devez-vous effectuer des contrôles de sécurité ailleurs auparavant, ou cela rendra-t-il le code plus complexe?
Utilisez trop d’indices indirects et tout redevient un gâchis… comme pour d’autres principes, celui-ci sera en conflit avec d’autres, comme KISS, YAGNI, etc. Tout est une question d’équilibre.
la source
"Principe de responsabilité unique" est peut-être un nom déroutant. "Une seule raison de changer" est une meilleure description du principe, mais il est encore facile de se méprendre. Nous ne parlons pas de dire ce qui cause les objets à changer d'état au moment de l'exécution. Nous discutons de ce qui pourrait amener les développeurs à devoir modifier le code à l'avenir.
Sauf si nous corrigeons un bogue, le changement sera dû à une exigence nouvelle ou modifiée. Vous devrez penser à l'extérieur du code lui-même et imaginer quels facteurs extérieurs pourraient entraîner une modification indépendante des exigences . Dire:
Idéalement, vous souhaitez que des facteurs indépendants affectent différentes classes. Par exemple, étant donné que les taux d'imposition changent indépendamment des noms de produits, les modifications ne devraient pas affecter les mêmes classes. Sinon, vous courez le risque de voir une modification de taxe introduire une erreur dans la dénomination du produit, qui est le type de couplage étroit que vous souhaitez éviter avec un système modulaire.
Donc, ne vous concentrez pas uniquement sur ce qui pourrait changer - tout pourrait éventuellement changer dans le futur. Concentrez-vous sur ce qui pourrait changer indépendamment . Les changements sont généralement indépendants s'ils sont causés par différents acteurs.
Votre exemple avec des titres d'emploi est sur la bonne voie, mais vous devriez le prendre plus littéralement! Si le marketing peut entraîner des modifications du code et que les finances peuvent entraîner d'autres modifications, celles-ci ne doivent pas affecter le même code, car elles portent littéralement des intitulés de postes différents et, par conséquent, les modifications sont apportées indépendamment.
Pour citer Oncle Bob qui a inventé le terme:
Donc, pour résumer: une "responsabilité" est de s'occuper d'une seule fonction commerciale. Si plus d'un acteur peut vous obliger à changer de classe, la classe enfreint probablement ce principe.
la source
Un bon article qui explique les principes de la programmation SOLID et donne des exemples de code respectant et ne respectant pas ces principes est https://scotch.io/bar-talk/solid-the-first-five-principles-of-object-oriented- conception .
Dans l'exemple relatif à SRP, il donne un exemple de quelques classes de formes (cercle et carré) et une classe conçue pour calculer la surface totale de plusieurs formes.
Dans son premier exemple, il crée la classe de calcul d'aire et la renvoie en sortie au format HTML. Plus tard, il décide de l’afficher au format JSON et doit changer de classe de calcul de zone.
Le problème de cet exemple est que sa classe de calcul d'aire est responsable du calcul de l'aire des formes ET de l'affichage de cette aire. Il utilise ensuite une autre classe spécialement conçue pour afficher les zones.
Ceci est un exemple simple (et plus facile à comprendre en lisant l'article car il contient des extraits de code), mais illustre l'idée de base de SRP.
la source
Tout d’abord, vous avez en fait deux problèmes distincts : le problème des méthodes à mettre dans vos classes et le problème de la surcharge d’interface.
Des interfaces
Vous avez cette interface:
On peut supposer que vous avez plusieurs classes conformes à l'
CustomerCRUD
interface (sinon une interface n'est pas nécessaire), ainsi que certaines fonctionsdo_crud(customer: CustomerCRUD)
qui prennent un objet conforme. Mais vous avez déjà rompu le PÉR: vous avez lié ces quatre opérations distinctes.Disons que plus tard, vous utiliserez des vues de base de données. Une vue de base de données ne dispose que de la
Read
méthode disponible. Mais vous voulez écrire une fonctiondo_query_stuff(customer: ???)
qui exploite les opérateurs de manière transparente sur des tables ou des vues complètes; il utilise seulement leRead
méthode, après tout.Alors créez une interface
public Interface CustomerReader {public client lu (customerID: int)}
et factorisez votre
CustomerCrud
interface comme:Mais il n'y a pas de fin en vue. Il peut y avoir des objets que nous pouvons créer mais pas mettre à jour, etc. Ce trou de lapin est trop profond. Le seul moyen sensé de respecter le principe de responsabilité unique est de faire en sorte que toutes vos interfaces contiennent exactement une méthode. . Go suit effectivement cette méthodologie de ce que j'ai vu, avec la grande majorité des interfaces contenant une seule fonction; Si vous souhaitez spécifier une interface contenant deux fonctions, vous devez créer maladroitement une nouvelle interface combinant les deux. Vous obtenez bientôt une explosion combinatoire d'interfaces.
La solution à ce problème consiste à utiliser un sous-typage structurel (implémenté dans, par exemple, OCaml) au lieu d’interfaces (qui sont une forme de sous-typage nominal). Nous ne définissons pas d'interfaces; à la place, nous pouvons simplement écrire une fonction
cela appelle toutes les méthodes que nous aimons. OCaml utilisera l'inférence de type pour déterminer si un objet implémentant ces méthodes peut être transmis. Dans cet exemple, il serait déterminé que
customer
a type<read: int -> unit, update: int -> unit, ...>
.Des classes
Cela résout le désordre d' interface ; mais nous devons encore implémenter des classes contenant plusieurs méthodes. Par exemple, devrions-nous créer deux classes différentes,
CustomerReader
etCustomerWriter
? Que se passe-t-il si nous voulons changer la manière dont les tables sont lues (par exemple, nous mettons maintenant en cache nos réponses dans les redis avant de récupérer les données), mais comment sont-elles écrites? Si vous suivez cette chaîne de raisonnement jusqu'à sa conclusion logique, vous êtes entraîné inextricablement à la programmation fonctionnelle :)la source
Dans mon esprit, la chose la plus proche d'un SRP qui me vient à l'esprit est un flux d'utilisation. Si vous ne disposez pas d'un flux d'utilisation clair pour une classe donnée, votre classe a probablement une odeur de design.
Un flux d'utilisation serait une succession d'appels à une méthode donnée qui vous donnerait un résultat attendu (donc vérifiable). En gros, vous définissez une classe avec les cas d’utilisation qu’il a obtenus à mon humble avis, c’est pourquoi toute la méthodologie du programme met l’accent sur les interfaces plutôt que sur la mise en oeuvre.
la source
C’est pour parvenir à ce que de multiples changements d’exigences ne nécessitent pas que votre composant change .
Mais bonne chance à comprendre qu'à première vue, lorsque vous entendez parler de SOLID.
Je vois beaucoup de commentaires disant que SRP et YAGNI peuvent se contredire, mais que YAGN I a été mis en application par TDD (GOOS, London School) m'a appris à penser et à concevoir mes composants du point de vue d'un client. J'ai commencé à concevoir mes interfaces avec le minimum que tout client souhaite faire, c'est peu de choses qu'il devrait faire . Et cet exercice peut être fait sans aucune connaissance de TDD.
J'aime la technique décrite par Oncle Bob (malheureusement, je ne me souviens pas d'où), qui se présente comme suit:
Cette technique est un absolu et, comme @svidgen l’a dit, le SRP est un jugement, mais quand on apprend quelque chose de nouveau, les absolus sont ce qu’il ya de mieux, il est plus facile de toujours faire quelque chose. Assurez-vous que la raison pour laquelle vous ne vous séparez pas est; une estimation éclairée, et non pas parce que vous ne savez pas comment. C'est l'art, et cela prend de l'expérience.
Je pense que beaucoup de réponses semblent argumenter en faveur du découplage quand on parle de SRP .
SRP est pas pour vous assurer un changement ne se propage pas sur le graphe de dépendance.
Théoriquement, sans SRP , vous n'auriez aucune dépendance ...
Un changement ne devrait pas causer de changement à plusieurs endroits dans l'application, mais nous avons d'autres principes pour cela. SRP améliore cependant le principe de fermeture fermée . Ce principe concerne plus l'abstraction, cependant, les abstractions plus petites sont plus faciles à réimplémenter .
Ainsi, lorsque vous enseignez SOLID dans son ensemble, veillez à préciser que SRP vous permet de modifier moins de code lorsque les exigences changent, alors qu'en réalité, cela vous permet d'écrire moins de nouveau code.
la source
When learning something new, absolutes are the best, it is easier to just always do something.
- D'après mon expérience, les nouveaux programmeurs sont beaucoup trop dogmatiques. L'absolutisme conduit à des développeurs non-pensants et à une programmation culte du cargo. Dire "faites ceci" est bien, pourvu que vous sachiez que la personne à qui vous parlez devra désapprendre plus tard ce que vous lui avez enseigné.Il n'y a pas de réponse claire à cela. Bien que la question soit étroite, les explications ne le sont pas.
Pour moi, c'est un peu comme le rasoir d'Occam si vous le souhaitez. C'est un idéal où j'essaie de mesurer mon code actuel. Il est difficile de le décrire avec des mots clairs et simples. Une autre métaphore serait "un sujet" aussi abstrait, c'est-à-dire difficile à saisir, que "une seule responsabilité". Une troisième description serait "traitant d'un niveau d'abstraction".
Qu'est-ce que cela signifie concrètement?
Dernièrement, j'utilise un style de codage qui comprend principalement deux phases:
La phase I est décrite comme un chaos créatif. Dans cette phase, j'écris le code pendant que les pensées circulent - c'est-à-dire crues et laides.
La phase II est le contraire. C'est comme nettoyer après un ouragan. Cela prend le plus de travail et de discipline. Et ensuite, je regarde le code du point de vue d'un designer.
Je travaille principalement en Python maintenant, ce qui me permet de penser à des objets et à des classes plus tard. Première phase I - Je n'écris que des fonctions et les diffuse presque aléatoirement dans différents modules. Au cours de la phase II , une fois les travaux en cours, j’examine de plus près quel module traite quelle partie de la solution. Et en parcourant les modules, des sujets me sont apparus. Certaines fonctions sont liées thématiquement. Ce sont de bons candidats pour les cours . Et après avoir transformé les fonctions en classes - ce qui est presque fait avec l'indentation et l'ajout
self
à la liste des paramètres en python;) - j'utiliseSRP
comme Razor d'Occam pour supprimer les fonctionnalités des autres modules et classes.Un exemple courant peut être l’ écriture de petites fonctionnalités d’exportation l’autre jour.
Il y avait le besoin de CSV , Excel et des feuilles Excel combinées dans un zip.
La fonctionnalité simple a été réalisée dans trois vues (= fonctions). Chaque fonction utilisait une méthode commune pour déterminer les filtres et une seconde méthode pour récupérer les données. Ensuite, dans chaque fonction, l’exportation a été préparée et a été envoyée en tant que réponse du serveur.
Il y avait trop de niveaux d'abstraction mélangés:
I) traitement des demandes / réponses entrantes / sortantes
II) déterminer les filtres
III) récupération des données
IV) transformation des données
La première étape consistait à utiliser une seule abstraction (
exporter
) pour traiter les couches II à IV.Le seul reste était le sujet traitant des demandes / réponses . Au même niveau d'abstraction, l' extraction des paramètres de requête est satisfaisante. J'ai donc eu pour cette vue une "responsabilité".
Deuxièmement, je devais séparer l'exportateur qui, comme nous l'avons vu, consistait en au moins trois autres couches d'abstraction.
La détermination des critères de filtrage et la remontée effective se situent presque au même niveau d'abstraction (les filtres sont nécessaires pour obtenir le bon sous-ensemble de données). Ces niveaux ont été placés dans quelque chose comme une couche d'accès aux données .
Dans l'étape suivante, j'ai cassé les mécanismes d'exportation actuels: lorsqu'il était nécessaire d'écrire dans un fichier temporel, je l'ai divisé en deux "responsabilités": une pour l'écriture proprement dite des données sur disque et une autre partie concernant le format réel.
Lors de la formation des classes et des modules, les choses sont devenues plus claires, ce qui appartenait à où. Et toujours la question latente, si la classe en fait trop .
Il est difficile de donner une recette à suivre. Bien sûr, je pourrais répéter la règle «un niveau d’abstraction» cryptée si cela aide.
C'est surtout pour moi une sorte d '"intuition artistique" qui mène au design actuel; Je modélise le code comme un artiste peut sculpter de l'argile ou peindre.
Imagine-moi comme un codeur Bob Ross ;)
la source
Ce que j'essaie de faire pour écrire du code qui suit le SRP:
Exemple:
Problème: obtenez deux nombres de l'utilisateur, calculez leur somme et envoyez le résultat à l'utilisateur:
Ensuite, essayez de définir les responsabilités en fonction des tâches à exécuter. Extrayez les classes appropriées:
Ensuite, le programme refactorisé devient:
Remarque: cet exemple très simple ne prend en compte que le principe SRP. L'utilisation des autres principes (par exemple: le code "L" devrait dépendre d'abstractions plutôt que de concrétions) procurerait plus d'avantages au code et le rendrait plus facile à gérer en cas de changement d'activité.
la source
Extrait du livre de Robert C. Martins, Clean Architecture: Le Guide de l'artisan de la structure et de la conception de logiciels , publié le 10 septembre 2017, Robert écrit à la page 62 ce qui suit:
Donc, il ne s'agit pas de code. Le SRP consiste à contrôler le flux des exigences et des besoins de l'entreprise, qui ne peuvent provenir que d'une seule source.
la source