it-swarm-fr.com

Quelle est la taille d'une classe?

Je suis un développeur de longue date (j'ai 49 ans) mais plutôt nouveau pour le développement orienté objet. J'ai lu sur OO car Bertrand Meyer's Eiffel, mais j'ai fait vraiment peu OO programmation.

Le point est chaque livre sur OO Conception commence par un exemple d'un bateau, d'une voiture ou d'un objet commun que nous utilisons très souvent, et commençons à ajouter des attributs et des méthodes et expliquant comment ils modélisent l'état de l'objet et de ce qui peut être fait avec elle.

Donc, ils vont généralement quelque chose comme "mieux le modèle mieux il représente l'objet dans l'application et mieux tout ira".

Jusqu'ici tout va bien, mais, d'autre part, j'ai trouvé plusieurs auteurs qui donnent des recettes telles que "une classe devraient correspondre à une seule page" (j'ajouterais "sur quelle taille de moniteur?" Maintenant que nous essayons de ne pas pour imprimer le code!).

Prenons par exemple une classe PurchaseOrder, qui a une machine à états finie contrôlant son comportement et une collection de PurchaseOrderItem, l'un des arguments ici au travail est que nous devrions utiliser un PurchaseOrder Classe simple, avec quelques méthodes (peu plus qu'une classe de données) et avoir une PurchaseOrderFSM "Classe d'expert" qui gère la machine à états finie pour le PurchaseOrder.

Je dirais que cela tombe dans "l'envie de caractéristiques" ou "intimité intimité" classification de Jeff Atwood's odeurs de code Publier sur le codage d'horreur. Je voudrais juste appeler ça bon sens. Si je peux émettre, approuver ou annuler ma commande de commande réelle, la classe PurchaseOrder doit avoir issuePO, approvePO et cancelPO méthodes.

Cela ne va-t-il pas avec la "cohésion maximisée" et "minimiser le couplage" de vieux principes que je comprends comme pierres angulaires de OO?

En outre, cela ne peut-il pas aider à la maintenabilité de la classe?

29
Miguel Veloso

Une classe devrait utiliser le principe de responsabilité unique. Très très grandes classes que j'ai vues faire à beaucoup de choses, c'est pourquoi ils sont trop grands. Regardez chaque méthode et le code décidez qu'il s'agisse de la catégorie ou du code de dupliqué séparé est un indice. Vous pourriez avoir une méthode SIMPOPO, mais contient-elle 10 lignes de code d'accès aux données par exemple? Ce code ne devrait probablement pas être là.

27
Craig

Le plus gros problème avec de grandes classes est quand il s'agit de tester ces classes ou de leur interaction avec d'autres classes. La taille de la classe importante n'est pas un problème, mais comme toutes les odeurs, cela indique un potentiel problème. De manière générale, lorsque la classe est importante, c'est une indication que la classe fait plus qu'une seule classe devrait.

Pour votre analogie de voiture, si la classe car est trop grande, c'est probablement une indication qu'il doit être divisé en classe engine, classe doors, et classe windshields, etc.

7
Billy ONeal

Je ne pense pas qu'il existe une définition spécifique d'une classe étant trop grande. Cependant, j'utiliserais les lignes directrices suivantes pour déterminer si je devrais refacturer ma classe ou redéfinir la portée de la classe:

  1. Y a-t-il de nombreuses variables indépendantes les unes des autres? (Ma tolérance personnelle est d'environ 10 ~ 20 dans la plupart des cas)
  2. Y a-t-il de nombreuses méthodes conçues pour les cas d'angle? (Ma tolérance personnelle est ... Eh bien, ça dépend fort de mon humeur, je suppose)

En ce qui concerne 1, imaginez que vous définissez votre taille de pare-brise, la taille de la roue, le modèle d'ampoule à queue et 100 autres détails de votre classe car. Bien qu'ils soient tous "pertinents" à la voiture, il est très difficile de retracer le comportement de cette classe car. Et quand un jour, votre collègue accidentellement (ou, dans certains cas, intentionnellement) modifie la taille du pare-brise basée sur le modèle d'ampoule de la queue, il vous prend pour toujours pour savoir pourquoi le pare-brise ne s'intègre plus dans votre voiture.

En ce qui concerne 2, imaginez que vous essayez de définir tous les comportements qu'une voiture peut avoir dans la classe car, mais car::open_roof() sera uniquement disponible pour les convertibles et car::open_rear_door() ne s'applique pas à ces voitures à 2 portes. Bien que les convertibles et les voitures de 2 portes sont des "voitures" par définition, les implémenter dans la classe car complique la classe. La classe devient plus difficile à utiliser et plus difficile à maintenir.

Autres que ces 2 directives, je suggérerais une définition claire de la portée de la classe. Une fois que vous définissez la portée, mettez en œuvre la classe strictement basée sur la définition. La plupart du temps, les gens obtiennent une classe "trop ​​grande" à cause de la mauvaise définition de la portée, ou à cause des caractéristiques arbitraires ajoutées à la classe.

7
YYC

Dites ce dont vous avez besoin dans 300 lignes

Remarque: cette règle de base suppose que vous suivez l'approche "une classe par fichier" qui est propre à une bonne idée de maintenabilité

Ce n'est pas une règle absolue, mais si je vois plus de 200 lignes de code dans une classe, je me méfie. 300 lignes et cloches d'avertissement sont allumées. Lorsque j'ouvre le code de quelqu'un d'autre et trouvez 2000 lignes, je sais que c'est le temps refactoring sans même lire la première page.

La plupart du temps, cela revient à la maintenabilité. Si votre objet est si complexe que vous ne pouvez pas exprimer son comportement dans 300 lignes, cela sera très difficile pour quelqu'un d'autre de comprendre.

Je trouve que je me plie cette règle dans le modèle -> ViewModel -> Voir le monde où je crée un "objet de comportement" pour une page d'interface utilisateur, car il prend souvent plus de 300 lignes pour décrire la série complète de comportements sur une feuille. Cependant, je suis toujours nouveau dans ce modèle de programmation et trouver de bonnes façons de refactoriser/réutiliser les comportements entre les pages/images de vue qui réduisent progressivement la taille de mes menuisiers.

7
Jay Beavers

Allons-y en arrière:

Cela ne va-t-il pas avec la "cohésion maximisée" et "minimiser le couplage" de vieux principes que je comprends comme pierres angulaires de OO?

En fait, c'est une pierre angulaire de la programmation, dont OO n'est qu'un paradigme.

Je vais laisser Antoine de Saint-Exupéry Répondre à votre question (parce que je suis paresseux;)):

La perfection est obtenue, pas quand il n'y a rien de plus à ajouter, mais quand il n'y a plus rien à emporter.

Le plus simple la classe, plus vous serez confiant, c'est bien, plus ce sera entièrement Testez-le.

6
Matthieu M.

Je suis avec l'OP sur la classification de l'envyon. Rien ne m'irrite plus que d'avoir un tas de classes avec un tas de méthodes qui travaillent sur des internes d'une autre classe. OO== suggère que vous modélisez les données et les opérations sur ces données. Cela ne signifie pas que vous mettez les opérations dans un endroit différent des données! Il tente de vous amener à placer les données et ces méthodes ensemble.

Avec les modèles car et person ($ var] _ Prevalent, il serait comme mettre le code pour effectuer la connexion électrique, ou même tourner le démarreur, dans la classe person. J'espère que cela serait évidemment faux à tout programmeur expérimenté.

Je n'ai pas vraiment de taille de classe ou de méthode idéale, mais je préfère garder mes méthodes et mes fonctions monté sur un seul écran afin que je puisse voir leur intégralité tout au même endroit. (J'ai configuré VIM pour ouvrir une fenêtre de 60 lignes, ce qui se trouve juste autour du nombre de lignes sur une page imprimée.) Il existe des endroits où cela n'a pas beaucoup de sens, mais cela fonctionne pour moi. J'aime suivre la même ligne directrice pour les définitions de classe et essayer de conserver mes fichiers sous quelques "pages" longtemps. Tout ce qui est de plus de 300, 400 lignes commencent à se sentir peu difficile à manier (principalement parce que la classe a commencé à prendre trop de responsabilités directes).

3
dash-tom-bang

Lorsqu'une définition de classe a quelques centaines de méthodes, c'est trop grand.

1
C Johnson

Je suis entièrement d'accord avec l'utilisation du principe de responsabilité unique pour les cours, mais si cela est suivi et entraîne des grandes classes, alors soyez donc aussi. L'objectif réel devrait être que des méthodes et des propriétés individuelles ne soient pas trop grandes, complexité cyclomatique devrait être le guide là-bas et le suivant peut entraîner de nombreuses méthodes privées qui augmenteront la taille de la classe globale, mais la laissera lisible. et testable à un niveau granulaire. Si le code reste lisible, la taille n'est pas pertinente.

1
Lazarus

L'émission d'un bon de commande est souvent un processus compliqué qui implique plus que le bon de commande. Dans ce cas, en gardant la logique commerciale dans une classe distincte et que la commande de commande plus simple est probablement la bonne chose à faire. En général, cependant, vous avez raison - vous ne voulez pas de classes de "structure de données". Par exemple, votre méthode "Pomanager" Business Business Class 'issue() devrait probablement appeler la méthode de issue() de PO. Le PO peut ensuite définir son statut sur "émis" et notez la date d'émission, tandis que le pomaneur peut ensuite envoyer une notification aux comptes payables pour qu'ils soient informés d'une facture et une autre notification à l'inventaire, alors ils savent qu'il y a quelque chose qui arrive et la date prévue.

Toute personne qui pousse des "règles" pour la méthode/la taille de la classe n'a évidemment pas passé assez de temps dans le monde réel. Comme d'autres l'ont mentionné, il s'agit souvent d'un indicateur de refactorisation, mais parfois (en particulier dans le traitement de données ", le travail de type), vous devez vraiment écrire une classe avec une méthode unique qui s'étend sur 500 lignes. Ne vous remettez pas dessus.

1
TMN

Assez grand pour contenir toute la logique nécessaire pour effectuer son travail.

Assez petit pour être maintenu et suivre le principe de responsabilité unique .

0
RMalke