web-dev-qa-db-fra.com

Quel est le bon équilibre entre la cohérence du code et l'amélioration du code?

Récemment, j'ai eu une discussion avec un collègue concernant le style de code. Il faisait valoir que votre utilisation des API et les modèles généraux que vous utilisez devraient être aussi similaires que possible avec le code environnant, sinon avec la base de code dans son ensemble, tout comme vous le feriez avec l'apparence du code (positionnement de l'accolade, capitalisation, etc.) . Par exemple, si j'ajoutais une méthode à une classe DAO en C #, j'essaierais d'utiliser LINQ le cas échéant pour aider à rendre mon code propre et facile à maintenir, même si aucune des autres méthodes de cette classe ne l'utilisait. Cependant, mon collègue dirait que je ne devrais pas l'utiliser dans ce cas parce que ce serait contraire au style existant de cette classe et donc plus difficile à comprendre.

Au début, j'ai trouvé sa position plutôt extrême, mais après y avoir réfléchi pendant un certain temps, je commence à voir son point. Avec l'exemple hypothétique LINQ, peut-être que cette classe ne le contient pas parce que mes collègues ne connaissent pas LINQ? Si oui, mon code ne serait-il pas plus facile à maintenir pour mes collègues développeurs si je ne l'utilisais pas? D'un autre côté, si je crois vraiment que l'utilisation d'une telle technique entraînerait un code plus propre, alors ne devrais-je pas l'utiliser même si elle diffère radicalement du code environnant?

Je pense que le nœud de l'argument de mon collègue est que si nous essayons tous d'implémenter des fonctionnalités similaires dans une base de code de différentes manières, et que nous pensons chacun que notre chemin est "le meilleur", alors à la fin, le code dans son ensemble devient plus difficile comprendre. Cependant, pour le moment, je pense toujours que si nous suivons aveuglément le code existant, la qualité pourrira lentement avec le temps.

Alors, dans quelle mesure les modèles font-ils partie du style de code, et où devrions-nous tracer la ligne entre rester cohérent et apporter des améliorations?

55
Robert Johnson

Pour donner une réponse plus générale:

Dans un cas comme celui-ci, vous avez deux "meilleures pratiques" de programmation qui s'opposent: la cohérence du code est importante, mais il en va de même pour choisir la meilleure méthode possible pour accomplir votre tâche. Il n'y a pas une seule réponse correcte à ce dilemme; cela dépend de quelques facteurs:

  • Dans quelle mesure la méthode "correcte" est-elle bénéfique?

    • Parfois, la nouvelle pratique améliorée améliorera considérablement les performances, éliminera les bogues, sera beaucoup plus facile à programmer, etc. Dans un tel cas, je pencherais fortement pour l'utilisation de la nouvelle méthode. D'un autre côté, la "bonne façon" peut être un peu plus que du sucre syntaxique, ou une méthode idiomatique convenue pour faire quelque chose qui n'est pas réellement supérieur. Dans ce cas, la cohérence du code est probablement plus importante.
  • Quelle est l'ampleur d'un problème que créerait une incohérence?

    • Dans quelle mesure le nouveau code est-il interconnecté avec le code hérité? Votre nouveau code fait-il partie d'une bibliothèque? Crée-t-il un objet qui est transmis à de nombreuses parties du programme? Dans de tels cas, la cohérence est très importante. L'utilisation d'une nouvelle API, ou d'une nouvelle façon de faire les choses en général, pourrait créer des résultats subtilement différents qui briseraient les hypothèses ailleurs dans votre programme. D'un autre côté, si vous écrivez un morceau de code assez isolé, l'incohérence est moins susceptible d'être un problème.
    • Quelle est la taille et la maturité de votre base de code? Combien de développeurs ont besoin de le comprendre et de travailler dessus? Des normes convenues et cohérentes sont beaucoup plus importantes pour les grands projets.
    • Le code doit-il s'exécuter dans des environnements plus anciens qui ne prennent pas en charge les dernières fonctionnalités?

Sur la base de l'équilibre de ces problèmes, vous devez faire le bon choix sur l'itinéraire à prendre. Personnellement, je vois peu de valeur dans la cohérence pour des raisons de cohérence, et je préférerais utiliser les meilleures méthodes les plus récentes à moins qu'il y ait un coût important pour le faire.

Bien sûr, il y a une troisième option: réécrire le code existant pour qu'il utilise les meilleures méthodes et est cohérent. Il y a des moments où cela est nécessaire, mais cela a un coût élevé.

54
user82096

Rester cohérent a peu de valeur selon moi; apporter des améliorations en continu est un must.

La position de votre collègue entrave vraiment l'innovation. L'argument de cohérence vous place dans une situation où vous ne pouvez utiliser, par exemple, LINQ que si vous migrez tous du code pour utiliser LINQ. Et bien, nous n'avons pas le temps pour ça, n'est-ce pas?

Je préfère avoir une incohérence où du code fait encore foreach sur ArrayLists et d'autres parties utilisent LINQ sur IEnumerable<T>, au lieu de s'en tenir à la façon la plus ancienne de faire les choses jusqu'à la fin des temps.

Il est de la responsabilité de vos collègues de rester pertinents et d'apprendre de nouvelles façons de faire.

27
Joppe

La cohérence des API est très importante, à la fois pour les API publiques et internes.

La cohérence de la mise en forme du code est importante et devrait idéalement être appliquée par un outil de mise en forme automatique avec les mêmes règles de mise en forme pour tout le monde. Facilite la vie avec une base de code partagée contrôlée par la version.

Les conventions de dénomination doivent être cohérentes, également pour des choses comme les variables locales, etc.

Des outils d'analyse statique doivent être utilisés pour appliquer certaines autres conventions et bonnes pratiques (mais ne suivez pas aveuglément les valeurs par défaut d'un tel outil, les valeurs par défaut peuvent parfois frôler la folie), mais si quelque chose l'exige, n'ayez pas peur d'en désactiver certaines vérifier (généralement avec une directive dans un commentaire) temporairement, si vous pouvez le justifier.

Que se passe-t-il à l'intérieur des fonctions/méthodes, en dehors de ce qui est indiqué ci-dessus, n'a pas besoin d'être cohérent de quelque manière que ce soit, tant qu'il s'agit d'un bon code seul . Bon, compréhensible, bien code commenté est très important, mais après cela, si le compilateur et les outils d'analyse statique pensent que c'est du code cohérent, c'est assez cohérent.


À propos des nouvelles fonctionnalités de langue telles que LINQ (enfin, ce n'est pas exactement nouveau), la seule chose à considérer est la nouvelle version suffisante de la langue/des bibliothèques utilisée partout où le code sera utilisé? En cas de doute, respectez les fonctionnalités connues pour être compatibles. Bien sûr, cela ne vous empêche pas de pousser une mise à niveau de version dans tout le système, vous pouvez donc commencer à utiliser les nouvelles fonctionnalités de Nice.

Et chaque développeur travaillant avec du code devrait se tenir à jour, donc tout développeur .NET devrait connaître LINQ, et s'il ne le fait pas, il devrait être forcé d'apprendre, pour son propre bien (vous ne savez jamais quand vous chercherez un nouveau dans cette entreprise, pour une raison ou une autre).

8
hyde

La réponse est simple.

La cohérence est d'une importance capitale.

mais cela vient avec une mise en garde ...

Vous et votre collègue êtes probablement obsédés par le mauvais type de cohérence

Les implémentations sont jetables. Ils peuvent être complètement révisés avec plus ou moins de facilité en fonction de la qualité et de l'exhaustivité de la suite de tests. S'inquiéter de choses comme "Est-ce que cela devrait être une propriété?", "Le code mince ne devrait-il pas utiliser LINQ au lieu d'une construction de niveau inférieur?" est d'une valeur douteuse. Il est difficile de lier des mesures à la valeur de cohérence au niveau de la mise en œuvre. Une bien meilleure question à poser à ce niveau est "Est-ce que ce code fonctionne comme annoncé?". La cohérence d'implémentation de TL; DR est l'endroit où les "petits esprits" obtiennent leur hobgoblin.

Pourquoi la cohérence n'est-elle pas aussi importante ici? Les implémentations ont généralement un petit nombre de contributeurs. La plupart des méthodes sont écrites et ne sont plus jamais touchées. Du code restant, le nombre de méthodes qui ont deux contributeurs sont presque certainement une majorité. Ce schéma se poursuit à l'infini . Dans ce contexte, la cohérence n'est tout simplement pas si importante. Si la durée de conservation du code est assez petite ( quelques années ), les gains d'une cohérence agressive sont probablement un non-facteur.

Cela ne veut pas dire que vous devriez devenir fou dans vos implémentations. C'est plutôt dire qu'une conception agréable, propre et simple aura des ordres de grandeur plus précieux pour votre futur responsable hypothétique qu'une méthode de consistance de plaque de chaudière idiote. Cela nous amène au vrai point ...

les API ne sont pas jetables.

Il s'agit du niveau de code de toutes les API, des services Web, des SDK, etc. Ceux-ci doivent, doivent, DOIVENT être cohérents. Les gains de productivité de cette variété de cohérence sont énormes pour plusieurs raisons:

Tests d'intégration:

Si vous maintenez la cohérence de votre API, vous pouvez créer des suites de tests d'intégration. Ceux-ci permettent aux développeurs d'échanger librement les détails de mise en œuvre et d'obtenir une validation immédiate. Voulez-vous échanger vos conneries de collaboration avec LINQ? Les tests d'intégration s'exécutent-ils? Il fournit également une validation lors de la préparation de la mise en production. Parce que les ordinateurs sont rapides, un seul ordinateur portable peut effectuer le travail d'un millier de testeurs exécutant des tâches banales. Cela revient à augmenter considérablement les effectifs de votre organisation.

Productivité

Lorsque les API sont cohérentes, vous pouvez deviner comment utiliser une API simplement en suivant ce que vous avez appris sur l'utilisation d'autres parties de l'API. En effet, l'API offre un "aspect et une sensation" naturels et cohérents. Cela signifie que votre client passe moins de temps à parcourir la documentation. L'intégration est plus facile et moins chère. Moins de questions sont posées aux personnes qui ont développé l'API. La cohérence fait de chacun un gagnant

Pourquoi la cohérence est-elle importante dans ce scénario? Parce que les API ont exactement le problème opposé des implémentations. Le nombre de personnes qui les utilisent est généralement beaucoup plus élevé que le nombre de personnes contribuant à leurs implémentations. Les petits gains d'un peu de cohérence sont multipliés et les coûts de maintien de cette cohérence sont amortis.

Conclusion

La cohérence coûte cher. À première vue, il réduit la productivité. Cela contraint les développeurs et leur rend la vie plus difficile. Il impose des limites sur la façon dont ils peuvent résoudre un problème, les forçant parfois à le résoudre de manière non optimale. C'est souvent pour des raisons qu'ils ne comprennent pas, sont mal conçus ou ne sont pas au courant (contrats, politiques organisationnelles ou inter-organisationnelles plus larges).

Raymond Hettinger a fait d'excellents points dans son discours sur Pycon 2015 concernant l'utilisation du guide de style PEP8 pour les équipes de programmeurs python. Il a montré que l'obsession de la cohérence stylistique d'un morceau de code faisait manquer les réviseurs de code) de graves défauts de logique et de conception. Son hypothèse peut être résumée comme trouver des incohérences stylistiques est facile; déterminer la qualité réelle d'un morceau de code est difficile

Le point ici est critique. Identifiez où la cohérence est importante et protégez-la de manière agressive. Où ce n'est pas important, ne perdez pas votre temps. Si vous ne pouvez pas fournir un moyen objectif de mesurer la valeur de la cohérence (dans les cas ci-dessus "effectif effectif", coût en fonction de la productivité) et que vous ne pouvez pas démontrer que les rendements sont substantiels, alors vous ne rendez probablement pas service à ton organisation.

6
nsfyn55

Vous ne connaissez pas LINQ? Si oui, mon code ne serait-il pas plus facile à maintenir pour mes collègues développeurs si je ne l'utilisais pas?

Le langage C # évolue toujours. Si les gens n'apprenaient pas les changements de C # 1, ils manqueraient:

  • Génériques
  • Partiels
  • Méthodes anonymes
  • Itérateurs
  • Types nullables
  • Auto-propriétés
  • Types anonymes
  • Méthodes d'extension
  • Lingue
  • Lambdas
  • Méthodes asynchrones

Ceci est juste une petite sélection de fonctionnalités communes trouvées dans l'article Wikipedia. Le point que je fais est que si les développeurs n'apprennent pas, la base de code restera dans le vide. On pourrait espérer que vos développeurs s'améliorent continuellement et que la base de code évolue, soutenue par une suite de tests complète. Vous souvenez-vous à quel point c'était mauvais avec .NET 1 pour implémenter manuellement les propriétés.

Linq vous facilite la vie. Utilisez-le où vous le pouvez. Vous pourriez motiver les membres de votre équipe.

Alors, dans quelle mesure les modèles font-ils partie du style de code, et où devrions-nous tracer la ligne entre rester cohérent et apporter des améliorations?

Les améliorations sont progressives. Pour moi, cela n'a aucun sens de conserver l'ancien code de style qui est moins lisible et potentiellement moins maintenable. Les membres de votre équipe devraient au moins être capables de comprendre ce qui se passe, même s'ils ne peuvent pas l'écrire.

4
Sam

Vous devez être cohérent, mais pas nécessairement avec l'ancien code. C'est-à-dire que votre équipe doit se mettre d'accord sur la bonne façon de faire quelque chose et l'utiliser de cette façon chaque fois qu'un nouveau code est écrit ou que des modifications substantielles sont apportées.

De cette façon, vous récoltez la plupart des avantages de la cohérence (en particulier, peu importe qui écrit le code), mais vous pouvez toujours vous améliorer si l'équipe voit un avantage clair en faisant les choses d'une autre manière.

Dans un monde idéal, nous réécririons tout l'ancien code pour qu'il se conforme à la nouvelle façon correcte. Bien que cela ne soit pas économiquement viable, cela devrait avoir un sens technique (ou bien, la nouvelle façon n'est pas une meilleure façon), et votre plan à long terme devrait être de le mettre à niveau. Si cela n'en vaut pas la peine, ne vous embêtez pas avec la nouvelle façon. Autrement dit, il doit y avoir un net avantage à la nouvelle façon d'envisager de la déclarer la bonne.

3
meriton

Je pense qu'il est important de suivre un code style dans un projet par exemple. conventions de dénomination, indentations, etc.

Je ne suis pas d'accord pour dire que vous ne devriez pas utiliser de nouvelles constructions de langage ou de nouveaux modèles de conception simplement parce que vos collègues ne les comprennent pas ou qu'ils n'ont pas été utilisés dans le projet auparavant.

Bien sûr, ces choses devraient avoir de bonnes raisons de les utiliser, par exemple. performance ou concision, le cas échéant.

1
ozz

Je serais extrêmement prudent en suivant aveuglément les modèles de conception actuels. Bien sûr, lorsqu'il n'y a pas d'inconvénient appréciable, il faut toujours essayer de suivre des modèles similaires à travers la base de code.

Cependant, il est beaucoup trop facile d'entrer dans des circonstances où la majorité des développeurs ont l'impression que c'est "la meilleure pratique" de suivre les mauvais modèles existants conduisant à des situations où les bons développeurs écrivent du code mauvais et non maintenable.

D'un autre côté, la cohérence est importante. Lorsqu'il s'agit d'énormes bases de code, il est extrêmement utile d'essayer de suivre des modèles similaires de sorte que même si les développeurs n'ont pas lu chaque pouce de la base de code, ils savent à quoi s'attendre.

Par conséquent, je pense qu'il est préférable d'établir et de mettre à jour des directives sur les modèles que les développeurs doivent suivre si possible. De cette façon, tout nouveau code est cohérent avec les autres nouveaux codes.

0
user606723