Garder mes classes et méthodes aussi petites que possible?

20

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?

Florents Tselai
la source
10
Cela devrait être"As small as possible, but no smaller."
StuperUser
"Je veux dire par exemple, est-ce digne d'avoir une classe avec seulement 2 attributaires?" - Cela peut être, recherchez "Obsession primitive" (par exemple jamesshore.com/Blog/PrimitiveObsession.html )
Torsten
Je pense que la source de confusion est le mot "possible". Le principe devient ridicule si "possible" se réfère uniquement au code, car la plus petite classe possible qui fait quoi que ce soit d'utile n'a qu'une seule méthode (et dans certains cas zéro). Le candidat avait très probablement l'intention de prendre en compte la cohésion et le couplage.
Kelvin

Réponses:

23

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 .

Péter Török
la source
1
certainement une règle à ne pas suivre aveuglément, trop de petites classes est bien pire que quelques classes plus grandes la plupart du temps.
Ryathal
4
Ma règle d'or personnelle est la suivante: si vous ne pouvez pas voir une implémentation de méthode entière sur l'écran à la fois, refactorisez.
Dan Ray
6
@DanRay, oui, j'avais l'habitude d'avoir la même règle, jusqu'à ce que je lise Clean Code . Ce fut un choc, mais progressivement mon optimum est descendu à environ 10 lignes.
Péter Török
2
IMO Clean Code est horrible dans son extrémité vers les petites méthodes. Le problème est que lorsque les méthodes sont réduites, il y en aura plus. Bien sûr, les méthodes trop longues sont trop longues, mais Bob Martin semble préférer 10 méthodes 1 ligne à 1 méthode 10 lignes (donc le même code prend environ 5 fois plus d'espace à l'écran). Peut-être que c'est censé être une sorte de truc éducatif, je ne peux pas croire que quelqu'un pense vraiment que le code dans ce livre est bon.
Joonas Pulakka
5
@JoonasPulakka - Disons simplement que je n'ai jamais lu une méthode et pensé: "J'aimerais que cette méthode fasse plus." En raccourcissant les méthodes, vous pouvez écrire des noms de méthode très descriptifs qui peuvent souvent éliminer la nécessité de lire entièrement le corps de la méthode. J'ai trouvé les conseils de Clean Code très judicieux. Nous devrons simplement accepter d'être en désaccord. :)
David Harkness
9

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.

c_maker
la source
2

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.

Sardathrion - Rétablir Monica
la source
2

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

KCT
la source
2

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.

un CVn
la source
0

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.

Alan Delimon
la source
Ne réduisez jamais les méthodes plutôt que de suivre SRP et il fera automatiquement le travail.
Vinay Prajapati
0

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"

Peter Kofler
la source