web-dev-qa-db-fra.com

Comment le fait d'avoir trop de variables d'instance conduit-il à du code en double?

Selon Refactoring aux modèles :

Lorsqu'une classe essaie d'en faire trop, elle apparaît souvent comme trop de variables d'instance. Lorsqu'une classe a trop de variables d'instance, le code dupliqué ne peut pas être loin derrière.

Comment le fait d'avoir trop de variables d'instance conduit-il à du code en double?

19
q126y

Le fait d'avoir trop de variables d'instance n'est pas directement lié au code en double, ou vice versa. Cette affirmation, dans cette généralité, est fausse. On peut jeter deux classes distinctes sans code en double dans une classe - ce qui produit une nouvelle classe avec des responsabilités non séparées et trop de variables d'instance, mais toujours pas de code en double.

Mais lorsque vous trouvez une classe avec trop de responsabilités dans le code hérité du monde réel, les chances sont élevées que le programmeur qui l'a écrit ne se soucie pas du code propre ou des principes SOLID (du moins, pas à l'époque) quand il a écrit ce code), il n'est donc pas improbable que vous y trouviez d'autres odeurs de code en double.

Par exemple, l'anti-motif "réutilisation copier-coller" est souvent appliqué en copiant une ancienne méthode et en y apportant quelques légères modifications, sans refactorisation appropriée. Parfois, pour que cela fonctionne, il faut dupliquer une variable membre et modifier aussi légèrement cette variable. Cela pourrait entraîner une classe avec trop de variables d'instance (plus précis: trop de variables d'instance très similaires). Dans une telle situation, les variables d'instance similaires peuvent être un indicateur de code répété ailleurs dans la classe. Cependant, comme vous l'avez noté, il s'agit d'un exemple artificiel et je n'en conclurais pas une règle générale.

23
Doc Brown

Trop de variables d'instance signifie trop d'état. Trop d'état conduit à un code dupliqué qui n'est que légèrement différent pour chacun des états.

C'est une classe concrète unique classique qui fait trop de choses qui devraient être des sous-classes ou des compositions.

Trouvez quelques classes qui ont trop de variables d'instance, vous verrez qu'elles maintiennent beaucoup trop d'état et ont beaucoup de chemins de code dupliqués qui ne sont que légèrement spécialisés pour chaque cas, mais si compliqués qu'ils ne peuvent pas être séparés en méthodes réutilisables. C'est l'une des plus grandes sources de side effects ainsi que.

Il y a au moins une exception à cela qui ne tombe pas dans cette catégorie et est un moyen facile de remédier à cela. Immutableles objets n'ont pas ce problème, car ils sont un état fixe, il n'y a aucune chance de gestion d'état alambiquée ou d'effets secondaires.

11
user7519

La déclaration que vous citez doit être vue dans un contexte spécifique.

D'après mon expérience, je ne peux pas confirmer que "de nombreuses variables d'instance indiquent en général du code dupliqué". Notez également que cela appartient au "code odeurs" et qu'il y aurait des odeurs contradictoires. Jetez un œil ici:

http://c2.com/cgi/wiki?CodeSmell

De manière amusante, vous constaterez que "trop de variables d'instance" est aussi bonne qu'une odeur de code que "trop peu de variables d'instance".

Mais il y a des problèmes avec les variables d'instance, que ce soit trop peu ou trop:

  1. Chaque variable d'instance peut signifier une sorte de statut de l'objet. Stati a toujours besoin d'un traitement soigneux. Vous devez vous assurer que vous avez couvert toutes les combinaisons possibles de stati afin d'éviter un comportement inattendu. Vous devez toujours clairement maintenant: quel est le statut de mon objet en ce moment? Sous cet angle, de nombreuses variables d'instance peuvent indiquer que la classe est devenue impossible à maintenir. Cela peut également indiquer qu'une classe fait trop de travaux, car elle a besoin de tant de stati.

  2. Chaque variable d'instance vous oblige à surveiller, quelles méthodes modifient la variable de quelle manière. Du coup, tu ne connais plus tous les cuisiniers qui cuisinent. L'un d'eux, programmé avec lassitude en fin de soirée, gâtera votre soupe. Encore une fois: trop de ces variables conduiront à un code difficile à pénétrer.

  3. L'autre côté: trop peu de variables d'instance peuvent faire en sorte que de nombreuses méthodes doivent gérer leurs informations avec trop de travail et avec trop de paramètres. Vous le ressentez, si vous donnez à plusieurs de vos méthodes un certain paramètre égal, et toutes les méthodes font quelque chose de très similaire avec ce paramètre. Dans cette situation, votre code commencera à gonfler. Vous finirez par faire défiler de nombreux écrans de haut en bas afin de rassembler des choses simples. Ici, une refactorisation peut aider: introduisez une variable d'instance et une entrée claire pour celle-ci. Ensuite, libérez toutes les méthodes.

  4. Dernier point mais non le moindre: si de nombreuses variables d'instance d'une classe ont chacune leur setter et leur getter, cela peut indiquer que d'autres classes n'utilisent pas cette première classe de la bonne façon. Il y a une discussion sur " Pourquoi les getters et setters sont mauvais ". L'idée en bref est que si une classe Rectangle propose une getX(), et que des dizaines d'autres classes utilisent rectangle.getX(), alors vous écrivez du code qui n'est pas robuste contre le " effet d'entraînement "(dans quelle mesure un changement de code influence-t-il un autre code). Demandez simplement ce qui se passe si vous changez le type de int en double? Selon cette discussion, la plupart des appels rectangle.getX() devraient en fait être des appels comme rectanlge.calculateThisThingForMe(). Donc, très indirectement, du code dupliqué pourrait émerger de nombreuses variables d'instance, car de nombreuses classes utilisent de nombreux getters et setters faisant des choses très similaires, c'est-à-dire des choses copiées, qui devraient mieux être déplacées à l'intérieur de la classe.

Beaucoup ou quelques variables d'instance restent un compromis permanent, modifiant les deux sens pendant la croissance du logiciel.

7
peter_the_oak

En termes simples: mauvaise séparation des préoccupations au sein du code, conduit à un code qui n'est pas modulaire, conduit à une mauvaise réutilisation, conduit à du code dupliqué.

Si vous n'essayez jamais de répéter la fonctionnalité, vous n'obtiendrez pas de code dupliqué et de nombreuses variables d'instance ne seront pas un problème.

Si vous essayez de répéter la fonctionnalité, le code monolithique, qui n'est pas modulaire, ne peut pas être réutilisé. Il en fait trop et ne peut que faire ce qu'il fait. Pour faire quelque chose de similaire, mais pas pareil, il est "plus facile" de couper et coller, plutôt que de briser le code monolithique. Les programmeurs d'expérience savent que le code dupliqué est le chemin de l'enfer.

Ainsi, bien que de nombreuses variables d'instance en elles-mêmes ne soient pas la cause première du problème, c'est une forte "odeur" que le problème vient.

Le langage "ne peut pas être loin derrière" est plus faible que de dire "doit sûrement suivre", de sorte que l'auteur ne prétend pas que cela doit arriver, mais finira par arriver; si vous devez réutiliser des fonctionnalités mais ne le pouvez pas car le code n'est pas modulaire.

6
simbo1905