Gestion du code: conserver un mauvais schéma lors de l’extension d’un nouveau code pour être cohérent ou non?


45

Je dois étendre un module existant d'un projet. Je n'aime pas la façon dont cela a été fait (beaucoup d'anti-pattern impliqué, comme du code copier / coller). Je ne veux pas effectuer un refactor complet pour plusieurs raisons.

Devrais-je:

  • créer de nouvelles méthodes en utilisant la convention existante, même si je me sens mal, afin d'éviter toute confusion pour le prochain responsable et d'être cohérent avec la base de code?

ou

  • essayer d'utiliser ce que je me sens mieux même s'il introduit un autre motif dans le code?

Precison édité après les premières réponses:

Le code existant n'est pas un gâchis. C'est facile à suivre et à comprendre. MAIS il introduit beaucoup de code passe-partout qui peut être évité avec une bonne conception (le code résultant pourrait alors devenir plus difficile à suivre). Dans mon cas actuel, c’est un bon vieux module DAO JDBC (spring template inboard), mais j’ai déjà rencontré ce dilemme et je cherche d’autres commentaires de développeurs.

Je ne veux pas refacturer parce que je n'ai pas le temps. Et même avec le temps, il sera difficile de justifier le fait que tout un module qui fonctionne parfaitement nécessite une refactorisation. Le coût du refactoring sera plus lourd que ses avantages. Rappelez-vous: le code n'est pas compliqué ou compliqué. Je ne peux pas extraire quelques méthodes et introduire une classe abstraite ici. C'est plus une faille dans la conception (résultat de l'extrême 'Keep It Stupid Simple' je pense)

La question peut donc aussi être posée comme cela:
vous, en tant que développeur, préférez-vous conserver du code ennuyeux et stupide, ou avoir des assistants capables de faire le code ennuyeux à votre place?

L'inconvénient de la dernière possibilité est que vous devrez apprendre des choses et peut-être que vous devrez aussi maintenir le code bête et ennuyeux jusqu'à ce qu'une refactorisation complète soit effectuée)


Question très intéressante!
Philippe

1
Conserver du code stupide, ennuyeux et facile - est par définition facile. Je préférerais avoir une vie facile et partir tôt chaque jour.
Rapidement maintenant

Oui, mais je suis trop paresseux pour faire du code stupide et ennuyeux :) Je préférerais travailler dur pendant 2 ou 3 jours pour construire quelque chose qui fera cette partie pour moi!
Guillaume

1
Quand est-ce que stupide ou ennuyeux est devenu confus pour facile?
Erik Reppen

Bonjour Erik, parfois un code qui aurait pu être factorisé est plus simple à lire: c’est une douzaine de fois la même chose et le code est simple. Vous pouvez le lire à la suite sans y penser et vous pouvez déboguer de manière linéaire. Il n'y a pas de complexité cachée.
Guillaume

Réponses:


42

La refactorisation est préférable de procéder par petites étapes, et de préférence uniquement si vous avez des tests unitaires pour couvrir le code. (Donc, si vous n'avez pas encore de tests, efforcez-vous de les écrire en premier, et en attendant, tenez-vous-en aux refactorisations les plus simples, les plus infaillibles, de préférence automatisées. Travailler efficacement avec Legacy Code de Michael Feathers est une aide précieuse.)

En général, essayez d’améliorer un peu le code chaque fois que vous le touchez. Suivez la règle du scoutisme ( inventée par Robert C. Martin ) en laissant le code plus propre que vous ne l'avez trouvé. Lorsque vous ajoutez un nouveau code, essayez de le garder séparé du mauvais code existant. Par exemple, ne l'enfouissez pas au milieu d'une méthode longue, ajoutez plutôt un appel à une méthode séparée et insérez votre nouveau code. De cette façon, vous développez progressivement des îlots de code plus propre dans la base de code existante.

Mise à jour

Le coût du refactoring sera plus lourd que ses avantages. [...] Vous, en tant que développeur, préférez-vous maintenir un code simple, ennuyeux et stupide OU avoir des assistants capables de créer le code ennuyeux et stupide chez vous?

J'ai souligné ce qui, à mon avis, est le point clé ici. Il est toujours utile d’évaluer les coûts et les avantages de la refactorisation avant de nous lancer. Comme dans votre cas, la plupart d’entre nous ont des ressources limitées pour la refactorisation, nous devons donc les utiliser judicieusement. Consacrez ce peu de temps précieux à la refactorisation là où elle apporte le plus d'avantages avec le moins d'effort.

En tant qu'esprit créatif, je préférerais bien sûr produire un code parfait, beau et élégant et réécrire tout ce qui ne ressemble pas à mes idéaux :-) En réalité, je suis payé pour produire un logiciel qui résolve les problèmes réels de ses utilisateurs. devraient penser à produire le plus pour leur argent à long terme.

L’avantage de la refactorisation n’apparaît que s’il ya suffisamment de temps et d’efforts pour comprendre, maintenir, corriger et étendre le code à long terme . Donc, si un morceau de code - aussi laid soit-il - est rarement ou jamais touché, il ne contient aucun bogue connu et je ne connais aucune fonctionnalité à venir qui nécessiterait que je le touche, je préfère partir. c'est en paix.


7
Il est si facile de tomber dans le piège de "le code est déjà nul, autant le garder en vie ..." Les bons programmeurs ne le font pas. Bonne réponse.
Sevenseacat

Bien que ce soit très probablement l'approche la plus sûre (le code est garanti pour fonctionner grâce aux tests), il en résulte toujours le problème mentionné dans la question. Un modèle différent est introduit dans le code. En général, je pense que vous devriez essayer de prendre tout votre temps pour tout refaire à la fois (lorsque vous utilisez TDD, mieux avec des étapes intermédiaires) afin de ne pas avoir cet état incohérent intermédiaire. Lorsque vous avez terminé, validez votre code pour le contrôle de source.
Steven Jeuris

2
@ Steven, il est bon de refacturer tout à la fois si vous pouvez vous le permettre . Cependant, dans la plupart des projets de la vie réelle, vous ne pouvez pas tout arrêter et passer plusieurs jours ou semaines d'affilée dans le seul refonte. Même si vous avez la chance d'avoir un responsable qui le supporte, le projet doit encore avancer.
Péter Török

1
@ Steven, ça dépend - voir ma mise à jour ci-dessus.
Péter Török

1
@ Péter Török: Belle mise à jour! Description parfaite des facteurs du monde réel à prendre en compte.
Steven Jeuris

4

Comme vous n'avez pas le temps de refactoriser et que le code est maintenable, maintenez-le cohérent. La prochaine fois, assurez-vous d'inclure la refactorisation dans l'estimation.


3

Être cohérent n'aide que le développeur suivant lorsque le code environnant est en bon état. Pensez au temps qu'il vous a fallu pour comprendre le code actuel et trouver les bons "points d'extension" pour ajouter vos modifications. Si vous suivez la tendance actuelle, alors le prochain type doit comprendre le code existant ainsi que votre nouveau code lorsqu'il doit apporter des modifications.

Si vous reformulez le code en fonctions significatives, le prochain utilisateur aura plus de facilité à comprendre ce qui se passe et devra déployer moins d'efforts pour ajouter ses modifications. Pense-y de cette façon. Supposons que le prochain gars, c'est vous. Que préféreriez-vous voir lorsque vous revisitez ce bloc de code, le même gâchis que vous êtes en train de regarder ou quelque chose de plus logique?


3

La cohérence a une haute priorité. Il est évident que tout le monde sensé préférerait une solution DRY élégante partout, au lieu d'un passe-partout copié-collé, mais préféreriez-vous vraiment deux approches différentes dans la même base de code qu'une application cohérente? Et si quelqu'un invente une solution encore plus intelligente et l'applique également de manière incohérente? Ensuite, vous avez trois façons différentes de faire la même chose.

J'ai constaté que beaucoup de code en désordre résultait du fait que les développeurs trouvaient un "meilleur moyen" de faire quelque chose, sans l'appliquer systématiquement sur une base de code. Si cela fait partie d'une stratégie planifiée et coordonnée d'appliquer un nouveau modèle au fil du temps, cela peut fonctionner, mais chaque modèle mis en œuvre de manière incohérente risque d'aggraver le système dans son ensemble.

Vous pourriez peut-être envisager une refactorisation par étapes plus petites, de telle sorte que chaque étape puisse être appliquée en une fois à la totalité du code. Par exemple. extraire une plus petite partie du passe-partout en une fonction d'assistance à chaque itération. Au fil du temps, vous vous retrouvez avec tous les standards dans une classe d'assistance. Cela peut paraître vraiment moche car il n’a pas été conçu, mais a grandi, mais vous pouvez le corriger maintenant car vous avez tout le code au même endroit.


+1 "Alors vous avez trois façons différentes de faire la même chose." Je l'ai constaté dans tous les projets d'entreprise sur lesquels j'ai travaillé. Je dirais que n'essayez même pas de refactoriser le code tant que vous n'avez pas parcouru le code pour vous assurer qu'il n'y a pas déjà un autre élément de code qui tente de prendre en charge le code moche que vous avez décidé de refactoriser. Parfois, il est préférable de s'en tenir à la convention standard, du moins jusqu'à ce que vous ayez lu le code en profondeur.
TK-421

1

Toute refactorisation qui élimine le code en double constitue une bonne refactorisation et ne devrait pas être reportée à moins qu'une échéance ne soit imminente. Le temps passé à refactoriser une fois est facilement compensé par le temps gagné lors de futures mises en œuvre. Grâce à la refactorisation, le fonctionnement interne n'est plus visible, il devrait donc être plus facile à comprendre et non plus difficile à suivre.

À mon avis, il est courant de croire à tort que le code refactoré est plus difficile à suivre. Ceci est généralement un argument de personnes qui ne connaissent que ce qui est refactoré, et non le résultat refactoré. Pour les nouveaux arrivants, le résultat refactorisé sera plus clair.

Tous les bogues / fonctionnalités peuvent être corrigés / implémentés ultérieurement dans un emplacement central et sont automatiquement disponibles partout dans votre application. C'est un gain énorme qui est généralement fortement sous-estimé. En général, la refactorisation totale d'un composant ne prend pas si longtemps. (jours au lieu de mois) Lorsque l'on compare cela au temps perdu à cause de bugs, qu'il faut comprendre le code qui aurait pu être refactoré, le coût de la refactorisation devient minime.

Mise à jour relative à la réponse de Péter Török: N'est-ce pas en reportant le refactoring "parce que cela prend du temps", le temps pour le refactoriser à un moment ultérieur augmente? Le refactoring ne devrait pas prendre longtemps, quand il est fait plus souvent.

Comment expliquer à votre employeur que vous passerez quelques jours à écrire du code qui n’ajoute rien au produit, est difficile et pose une question totalement différente. :)


1
"Comment expliquer à votre patron que vous passerez quelques jours à écrire du code qui n'ajoute rien au produit, qui est difficile et qui est une question totalement différente." Bel essai ;-) Malheureusement, dans la vraie vie, nous devons également résoudre ce problème. C'est pourquoi il est plus pratique d'aller par petites étapes. Une demi-heure de refactorisation peut être effectuée dans le cadre d'une tâche de deux heures, sans que votre responsable ait même besoin de le savoir. OTOH, deux journées complètes de refactorisation, passe rarement inaperçu.
Péter Török

@ Péter Török: J'ai mis à jour le post un peu. Bien sûr, vous avez encore des situations réelles où vous n'êtes pas autorisé à prendre le temps de procéder à une refactorisation. Mais je crois fermement qu'en théorie, c'est toujours du temps gagné. (sauf si vous savez que le code sur lequel vous travaillez ne sera plus supporté dans un proche avenir)
Steven Jeuris

comme on dit, en théorie, il n'y a pas beaucoup de différence entre la pratique et la théorie. Cependant, dans la pratique ... :-) Dans la vraie vie, il est possible que vous ne récupériez pas toujours le coût du refactoring. J'ai prolongé ma réponse à ce sujet.
Péter Török

1
Le refactoring qui supprime le code dupliqué n’est pas toujours bon; il est possible que deux méthodes soient identiques selon les règles commerciales actuelles, mais pas celles de demain. Par exemple, une AcmeLockerBankpersonne peut avoir une getRow(int itemIndex)méthode qui retourne index % 5et une AcmeButtonPanelpeut avoir une méthode identique car les tableaux des casiers et des boutons numérotent les choses de la même manière; Si aucune des banques de casiers d'aujourd'hui ne contient d'articles avec un index supérieur à 1000, mais certains panneaux de boutons, les futurs casiers utilisent un espacement de rangées différent pour les index de la plage 1000-1999 ...
supercat

1
... ajouter le comportement supplémentaire aux banques de casiers sera facile si les banques de casier et les banques de boutons ont des getRowméthodes distinctes , mais peut être plus difficile si les fonctions ont été fusionnées dans une méthode commune.
Supercat

0

Ne pouvez-vous pas créer une nouvelle interface / classe qui fonctionne comme une façade sur l'ancien code, tout en introduisant votre nouveau code dans votre propre style pouvant être facilement étendu?


0

Faites-le bien aller de l'avant. Utilisez des fonctions au lieu de couper et coller. Cela ne nécessite pas de refactoring, mais cela vous donne le début d'une fondation pour un refactoring futur.


0

En tant que développeur, préférez-vous maintenir un code simple, ennuyeux et stupide OU avoir des assistants capables de créer le code ennuyeux et stupide chez vous?

Je ne comprends pas la question révisée. Je pense que la plupart des gens, comme moi-même, préféreraient ne pas conserver de "code stupide et ennuyeux". Je ne sais pas ce que tu veux dire par aide, désolé.

L'affiche a répondu à leur propre question en n'apportant pas de grands changements pour le moment. Bon choix. L'arrogance d'un développeur me pose un problème: ils savent ce qu'il y a de mieux pour l'entreprise. Un grand refactoring en catimini ... parce que tu sais mieux que ton patron? Tout gestionnaire capable peut peser les avantages.

Si la refactorisation n'est pas une option, alors la question devient davantage une discussion sur le bon moment, le bon endroit, etc. pour le faire. La cohérence est très importante. Pourtant, le code de longue durée bénéficie souvent du "renouvellement". D'autres ont discuté de ça ...

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.