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)
la source
Réponses:
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
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.
la source
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.
la source
Ê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?
la source
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.
la source
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. :)
la source
AcmeLockerBank
personne peut avoir unegetRow(int itemIndex)
méthode qui retourneindex % 5
et uneAcmeButtonPanel
peut 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 ...getRow
méthodes distinctes , mais peut être plus difficile si les fonctions ont été fusionnées dans une méthode commune.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?
la source
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.
la source
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 ...
la source