Il y a quelques jours, je parlais à une candidate au doctorat en génie logiciel et à un moment donné, elle m'a dit:
Gardez vos classes et méthodes aussi petites que possible
Et je me demande si c'est toujours une bonne pratique.
Je veux dire par exemple, est-ce digne d'avoir une classe avec seulement 2 attributaires? Par exemple, dans certaines méthodes, j'ai besoin de paires d'entiers pour travailler. Dois-je écrire une classe "PairOfIntgers"?
Cette façon de penser pourrait-elle «casser» le code en trop de morceaux?
code-quality
coding-style
Florents Tselai
la source
la source
"As small as possible, but no smaller."
Réponses:
Il y a un grain de vérité dans ce conseil, mais à mon humble avis, il n'est pas très bien exprimé, donc facile à mal comprendre et / ou à prendre à un extrême stupide. Quoi qu'il en soit, cela devrait être une règle de base plutôt qu'une loi stricte. Et vous devez toujours impliquer dans ces règles la clause "dans des limites raisonnables" , ou "mais n'oubliez pas d'utiliser votre bon sens" :-)
Le grain de vérité est que dans la pratique, les classes et les méthodes ont toujours tendance à croître par nature et non à rétrécir . Une correction de bogue ici, une petite extension de fonctionnalité là-bas, la gestion d'un cas spécial là-bas ... et le tour est joué, votre classe autrefois soignée et petite commence à gonfler. Au fil du temps, votre code tend presque inévitablement à devenir un monstrueux gâchis de spaghettis - à moins que vous ne combattiez activement cette tendance par le refactoring . La refactorisation produit presque toujours de nombreuses classes / méthodes plus petites à partir de quelques grandes. Mais bien sûr, il y a une limite sensible à la miniaturisation. Le refactoring ne consiste pas à avoir des classes et des méthodes plus petites en soi, mais à rendre votre code plus propre, plus facile à comprendre et à maintenir. À un certain moment, réduire la taille de vos méthodes / classes commence à diminuer la lisibilité, plutôt que de l'augmenter. Visez cet optimum. C'est une zone cible floue et en mouvement, vous n'avez donc pas besoin de la toucher. Il suffit d' améliorer un peu le code chaque fois que vous remarquez un problème avec elle .
la source
Le problème le plus important à souligner ici est la création de bonnes abstractions . Les petites classes qui sont faiblement couplées et qui ont une cohésion élevée sont le produit de bonnes abstractions .
Parfois, il est parfaitement logique d'encapsuler deux entiers dans une classe. Surtout si vous voulez avoir des méthodes 'attachées' à cette classe pour encapsuler également comment on peut manipuler ces attributs et pour vous assurer de les protéger contre d'autres parties du programme qui les changent.
Un autre point positif pour créer une classe dans ce cas est que la classe peut évoluer beaucoup mieux / mieux que disons une structure de données de niveau inférieur comme une carte ou une liste.
Troisièmement, une bonne abstraction peut améliorer considérablement la lisibilité. Les classes qui adhèrent à SRP sont généralement beaucoup plus faciles à comprendre par un humain que les classes qui ne le font pas.
Et juste comme une note finale ... peu importe à quel point vous êtes bon d'un élève ... pour comprendre la POO et les bonnes abstractions et quand les utiliser, vous avez besoin d'expérience. Vous devez écrire du mauvais code et passer par la douleur pour le maintenir. Vous devez voir les autres écrire du bon code pour développer vos connaissances sur ce qui est «bon» et ce qui sera un problème sur la ligne ... Alors ne vous battez pas si vous ne l'obtenez pas tout de suite.
la source
L'anti-modèle God Object est ce à quoi elle faisait probablement allusion. J'ai tendance à penser que si j'ai un "et" dans ma description de classe, je devrais avoir deux classes. Si j'ai plus de dix lignes de code dans une méthode / fonction, je devrais la décomposer. En tant que code pirate, ce sont plus des directives que des règles.
la source
Dans la programmation orientée objet, le principe de responsabilité unique stipule que chaque objet doit avoir une responsabilité unique et que cette responsabilité doit être entièrement encapsulée par la classe. Habituellement, vous faites plus d'une chose si votre classe devient trop grande. Dans votre cas, la classe est juste une classe de données qui contient des données totalement correctes. Vous ne devez pas nommer la classe PairOfInteger. Que décrivent les entiers? Selon votre scénario, un tuple (comme en C #) peut également suffire. Et vous voudrez peut-être penser à une jambe de force au lieu d'une classe.
Essayez de garder vos classes petites. Et des méthodes encore plus petites. Peut-être 10 lignes?!? Actuellement, j'essaie d'utiliser la conception de flux et les composants basés sur les événements, ce qui semble aider à maintenir les classes petites. Au début, j'étais inquiet de participer à de nombreux cours, mais cela fonctionne vraiment !!! http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03/19/flow-design-cheat-sheet-ndash-part-i-notation.aspx http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03 /20/flow-design-cheat-sheet-ndash-part-ii-translation.aspx
la source
Rendez les choses aussi simples que possible, mais pas plus simples. C'est la règle que j'essaie de respecter. Parfois, il est en fait logique pour une classe de faire ce qui équivaut à proprement parler à plus d'une chose, si ces choses sont liées à un thème commun . Regardez .NET; il existe des tonnes de classes qui implémentent un grand nombre d'interfaces, chacune avec sa propre liste de membres requis. Une méthode peut finir par devenir un peu longue si elle fait quelque chose de complexe avec un certain nombre d'étapes intermédiaires qui sont toutes interconnectées et ne se prêtent donc pas très bien à une refactorisation plus poussée. (Refactoriser pour garder les méthodes courtes devrait en fin de compte concerner la lisibilité et la maintenabilité; si la méthode longue est plus lisible et / ou maintenable qu'une courte, toutes choses égales par ailleurs, je prendrai la longue n'importe quel jour.)
«Rendre les classes et les méthodes aussi petites que possible» est, à mon avis, peu judicieux. Comme le souligne @c_maker, le véritable défi consiste à fournir de bonnes abstractions. Votre exemple de regroupement de deux nombres est excellent, par exemple, si vous travaillez sur une implémentation d'arithmétique de nombres complexes, ou si sur un système Unix vous devez vous référer à un contexte utilisateur / groupe. Cela n'a pas beaucoup de sens si les chiffres représentent, par exemple, un ID de facture et un ID de produit à ajouter à cette facture.
la source
C'est un bon conseil, mais il doit être mis en œuvre de manière quelque peu intelligente. Certainement ne le suivez pas aveuglément.
Quand je regarde mon code, je sais si une méthode est trop grosse. S'il en fait trop et serait trop difficile à lire, il est temps de refactoriser.
Voici un bon exemple: vous avez une boucle et vous avez peut-être 60 lignes de code dans cette méthode. Dans ce cas, il est probablement temps de refactoriser car vous en faites probablement trop avec cette méthode.
Mais ce n'est pas une règle dure et rapide. C'est seulement quelque chose que vous apprenez en faisant. Et les autres développeurs avec lesquels vous travaillez ne sont pas toujours d'accord et peuvent vous appeler dans une révision de code ou autre.
la source
L'oncle Bob dit que vous devriez refactoriser / diviser / extraire vos méthodes jusqu'à ce qu'il soit impossible de les réduire . Cela se termine généralement par plusieurs méthodes de 3 ou 4 lignes chacune. Lorsque vous obtenez trop de méthodes, vous devez créer plus de classes.
Si vous essayez de suivre SRP et un niveau d'abstraction par méthode, ces règles vous sont utiles. Au moins, ils me servent bien. Viser "aussi petit que possible" me donne de petites méthodes raisonnables, car j'atteins généralement l'objectif.
Et il est toujours plus facile de comprendre des classes plus petites. Allez-y, lisez "Clean Code"
la source