Lors d'un récent entretien d'embauche, je ne pouvais pas répondre à une question à propos de SOLID - à part fournir le sens de base des divers principes. Cela me gêne vraiment. J'ai passé quelques jours à fouiller et je n'ai pas encore produit de résumé satisfaisant.
La question de l'entrevue était:
Si vous examiniez un projet .Net dont je vous ai dit de suivre rigoureusement les principes SOLID, qu'attendriez-vous de voir en termes de projet et de structure de code?
Je me suis effondré un peu, je n'ai pas vraiment répondu à la question, puis j'ai été bombardé.
Comment aurais-je pu mieux gérer cette question?
Réponses:
S = Principe de responsabilité unique
Donc, je m'attendrais à voir une structure de dossiers / fichiers et une hiérarchie d'objets bien organisée. Chaque classe / élément de fonctionnalité doit être nommé de manière à ce que sa fonctionnalité soit très évidente, et il ne doit contenir que la logique pour effectuer cette tâche.
Si vous voyiez d'énormes classes de gestionnaires avec des milliers de lignes de code, cela signifierait que la responsabilité unique n'est pas suivie.
O = principe ouvert / fermé
C’est essentiellement l’idée que de nouvelles fonctionnalités doivent être ajoutées via de nouvelles classes ayant un impact minimal sur les fonctionnalités existantes ou nécessitant une modification de ces fonctionnalités.
Je m'attendrais à voir beaucoup d'utilisation de l'héritage d'objet, du sous-typage, des interfaces et des classes abstraites pour séparer la conception d'une fonctionnalité de l'implémentation réelle, permettant ainsi à d'autres utilisateurs de venir et d'implémenter d'autres versions sans affecter les performances. original.
L = principe de substitution de Liskov
Cela concerne la possibilité de traiter les sous-types comme leur type parent. Cela sort de la boîte en C # si vous implémentez une hiérarchie d'objets héritée appropriée.
Je m'attendrais à voir le code traiter les objets communs comme leur type de base et appeler des méthodes sur les classes de base / abstraites plutôt que d'instancier et de travailler sur les sous-types eux-mêmes.
I = Principe de séparation des interfaces
Ceci est similaire à SRP. Fondamentalement, vous définissez des sous-ensembles de fonctionnalités plus petits en tant qu’interfaces et travaillez avec celles-ci pour que votre système reste découplé (par exemple, a
FileManager
pourrait avoir la seule responsabilité de traiter les E / S sur fichier, mais cela pourrait implémenter unIFileReader
etIFileWriter
contenant les définitions de méthode spécifiques pour la lecture. et écriture de fichiers).D = Principe d'inversion de dépendance.
Là encore, cela concerne le fait de garder un système découplé. Peut-être serez-vous à la recherche d’une bibliothèque .NET Dependency Injection utilisée dans la solution telle que
Unity
ouNinject
ou dans un système ServiceLocator tel queAutoFacServiceLocator
.la source
Beaucoup de petites classes et interfaces avec injection de dépendance partout. Dans un grand projet, vous utiliseriez probablement également un framework IoC pour vous aider à construire et gérer la durée de vie de tous ces petits objets. Voir https://stackoverflow.com/questions/21288/which-net-dependency-injection-frameworks-are-worth-looking-into
Notez qu'un grand projet .NET qui suit STRICTEMENT les principes de SOLID ne signifie pas nécessairement une bonne base de code à utiliser pour tout le monde. En fonction de l'identité de l'intervieweur, il / elle aurait peut-être souhaité que vous montriez que vous comprenez ce que signifie SOLID et / ou que vous vérifiez dogmatiquement que vous respectez les principes de conception.
Vous voyez, pour être solide, vous devez suivre:
S principe de responsabilité Ingle, de sorte que vous aurez beaucoup de petites classes chacun d'entre eux font une seule chose
Principe O Pen-Closed, qui, dans .NET, est généralement implémenté avec l'injection de dépendance, qui requiert également le I et le D ci-dessous ...
Le principe de substitution de L iskov est probablement impossible à expliquer en c # avec une ligne. Heureusement, d'autres questions s'y posent, par exemple https://stackoverflow.com/questions/4428725/can-you-explain-liskov-substitution-principle-with-a-good-c-sharp-example
Je NTERFACE Ségrégation Principe fonctionne en tandem avec le principe ouvert-fermé. Si cela était suivi à la lettre, cela signifierait préférer un grand nombre de très petites interfaces plutôt que quelques "grandes" interfaces
D ependency principe d'inversion des classes de haut niveau ne devraient pas dépendre des classes de bas niveau, les deux devraient dépendre des abstractions.
la source
Quelques éléments de base que je m'attendrais à voir dans le code d'un magasin qui a épousé SOLID dans son travail quotidien:
Un grand nombre de modèles adaptateur et composite - je m'attendrais à l'utilisation de nombreux modèles d'adaptateur (une classe implémentant une interface en "passant par la fonctionnalité d'une interface différente) pour simplifier l'insertion d'une dépendance développée légèrement différents endroits où sa fonctionnalité est également nécessaire. Des mises à jour aussi simples que le remplacement d'un consignateur de la console par un enregistreur de fichiers violeront le LSP / ISP / DIP si l'interface est mise à jour pour exposer un moyen de spécifier le nom de fichier à utiliser. au lieu de cela, la classe de consignateur de fichiers exposera les membres supplémentaires, puis un adaptateur fera ressembler le consignateur de fichiers à un consignateur de console en masquant le nouveau contenu, de sorte que seul l'objet qui capture tout cela doit connaître la différence.
De même, lorsqu'une classe doit ajouter une dépendance à une interface similaire à une interface existante pour éviter de changer d'objet (OCP), la réponse habituelle consiste à implémenter un motif Composite / Stratégie (une classe implémentant l'interface de dépendance et consommant plusieurs autres implémentations de cette interface, avec des quantités variables de logique permettant à la classe de passer un appel à une, à toutes ou à toutes les implémentations).
la source
Distrayez-les en discutant avec Jon Skeet de la façon dont le "O" dans SOLID est "inutile et mal compris" et faites-leur parler de la "variation protégée" d'Alistair Cockburn et du "projet de succession ou d'interdiction de Josh Bloch".
Bref résumé de l'article de Skeet (bien que je ne recommanderais pas de laisser son nom sans lire le billet de blog original!):
Le PO a demandé: "Comment aurais-je pu mieux gérer cette question?" En tant qu’ingénieur principal menant une entrevue, je serais infiniment plus intéressé par un candidat capable de parler intelligemment des avantages et des inconvénients de différents styles de conception de code que par une personne capable de produire une liste de points.
Une autre bonne réponse serait: «Cela dépend de la façon dont ils l'ont compris. Si tout ce qu'ils savent, ce sont les mots à la mode SOLID, je m'attendrais à un abus d'héritage, à une utilisation excessive des infrastructures d'injection de dépendance, un million de petites interfaces reflète le vocabulaire de domaine utilisé pour communiquer avec la gestion de produit .... "
la source
Il y a probablement plusieurs façons de résoudre ce problème avec des durées variables. Cependant, je pense que cela va plus dans le sens de "Savez-vous ce que SOLID signifie?" Donc, répondre à cette question revient probablement à cogner sur les points et à les expliquer en termes de projet.
Donc, vous vous attendez à voir ce qui suit:
la source
C'est une excellente question, même si je pense que c'est une question d'entretien difficile.
Les principes SOLID régissent réellement les classes et les interfaces, ainsi que leurs relations.
Cette question est vraiment une question qui a plus à voir avec les fichiers et pas nécessairement les classes.
Une brève observation ou une réponse que je voudrais donner est qu’en général, vous verrez des fichiers ne contenant qu’une interface, et souvent, la convention est qu’ils commencent par un «majuscule». Au-delà de cela, je mentionnerais que les fichiers n'auraient pas de code dupliqué (en particulier dans un module, une application ou une bibliothèque) et que ce code serait partagé avec précaution au-delà de certaines limites entre modules, applications ou bibliothèques.
Robert Martin aborde ce sujet dans le domaine du C ++ dans la conception d'applications C ++ orientées objectifs à l'aide de la méthode Booch (voir les sections Cohésion, Fermeture et Réutilisation) et dans le Code épuré .
la source