Comment aborder la refactorisation d'une application web existante?

11

J'ai beaucoup lu et réfléchi récemment, et je suis arrivé à la conclusion que je devrais peut-être repenser ma stratégie de développement Web. Je fais beaucoup de programmation à la volée, et depuis 2 ans que je travaille sur une application web PHP, ce qui aurait pu commencer comme un petit outil est devenu un gros projet. Mais il y a une tonne de code hérité de moi et de mon prédécesseur, un extrait de code qui aurait peut-être du sens à l'époque, mais maintenant je remets en question l'utilité de ce code sous sa forme actuelle. De plus, des choses comme les tests unitaires et le développement piloté par les tests n'étaient pas de mon ressort jusqu'à tout récemment.

Comment aborderiez-vous la refactorisation de l'application Web? Quelles seraient les choses que je devrais rechercher et dans quel ordre? Qu'en est-il du jeu par navigateur et de l'application Web fonctionnelle? Y aurait-il alors une différence d'approche?

Eldros
la source
4
Si ce n'est pas cassé, ne le réparez pas. Passez plus de temps à écrire des tests et moins de temps à apporter des modifications inutiles.
Macneil
Juste par intérêt. Quel langage / technologies avez-vous utilisé pour rédiger votre candidature? De quel type de site s'agit-il? Voir welie.com/patterns -> Contexte de conception -> Types de sites
JW01
@ JW01 J'utilise PHP pour la logique interne et AJAX pour la gestion des vues et la validation des formulaires. Ce serait une variante du modèle d'application Web, mais uniquement disponible dans un environnement donné, car il s'agit d'un outil interne.
Eldros
J'avais une image complètement différente de votre application dans ma tête lorsque j'ai répondu à la question. Vous avez tellement plus de liberté pour changer l'API que si elle était dans le domaine public.
JW01
@ JW01 Je ne voulais pas être trop précis, car je voulais que cette question soit utile aux autres aussi.
Eldros

Réponses:

6

À peu près de la même manière que vous approchez de tout type de code hérité. Vous trouvez une pièce qui peut être testée, vous écrivez des tests pour elle, et refactorisez.

Si vous ne trouvez pas un morceau facilement testable, vous devrez le rendre testable sans le harnais de sécurité d'une suite de tests, auquel cas vous changez très soigneusement un morceau de code presque testable afin qu'il soit testable.

Le code qui ne rend pas les choses au navigateur - code "infrastructure", modèles, éléments touchant à la base de données - pourrait être un bon point de départ.

Edit: UI testing: Avec l'avertissement que j'ai peu d'expérience ici, un de mes amis fait ceci: il exécute un morceau de code générateur de HTML. Ensuite, il pirate son code et compare le code nouvellement généré à l'ancienne version (en utilisant diff; il n'a pas automatisé complètement). Les changements dans le HTML signifient que votre refactoring s'est cassé.

Frank Shearar
la source
Comment recommanderiez-vous de tester la partie "affichage" d'une application héritée - IE, la partie HTML / JavaScript / CSS / etc? Je suis d'accord que le test unitaire est la voie à suivre, mais le test du code d'application semble difficile à automatiser.
Justin Ethier
lors de la création de tests pour une interface utilisateur Web - comparer l'ancien HTML au nouveau HTML est une façon un peu fragile de faire les choses. J'ai tendance à identifier la sémantique d'une page Web et à tester cela. C'est-à-dire: "L'empreinte Web (titre de la page, titre, mots-clés, liens sortants, formulaires) a-t-elle changé?" pas "Le HTML a-t-il changé?".
JW01
Vous pouvez tester des applications Web avec un `` navigateur sans tête '' - essentiellement une bibliothèque qui est pour un test unitaire ce qu'est un navigateur pour un gars d'AQ. Dans le monde java, il existe HTMLUnit (java pur, autonome) et WebDriver (contrôle à distance un véritable navigateur comme FireFox). Mon projet a une suite de centaines de tests écrits comme ça.
Tom Anderson
@ JW01 Vous avez absolument raison - c'est très fragile. C'est génial pour tester un refactoring d'une manière unique: vous pouvez vérifier que le refactoring n'a pas changé la sortie, mais chaque fois que vous modifiez le HTML généré, vous devez enregistrer le HTML "nouveau attendu".
Frank Shearar
10

Il y a un grand livre à ce sujet intitulé "Travailler efficacement avec Legacy Code" par Michael Feathers. Avouons-le, nous avons tous un code hérité.

L'essentiel est de tester le nouveau code que vous créez. Comme vous devez toucher d'autres morceaux de code, vous trouverez également des opportunités pour les tester. C'est un processus long et lent, mais si vous le faites systématiquement, vous pouvez vraiment améliorer le produit global au fil du temps.

Marcie
la source
3
"Avouons-le, tout ce que nous faisons, c'est écrire le logiciel hérité de demain aujourd'hui." - Martin Fowler
Frank Shearar
3
  • Oui - les applications Web sont différentes des sites Web

Je les traiterais séparément. Si vous avez une partie de votre site qui est simplement une collection de documents (qui ressemblent aux utilisateurs anonymes et aux utilisateurs connectés) - alors la meilleure méthode de structuration est très différente d'une application Web qui sert des pages dynamiquement différentes à chaque utilisateur. Divisez ces deux parties du site en deux applications / composants et abordez chaque partie différemment.

  • Commencer à utiliser le contrôle de version

Une fois que votre code est sous contrôle de version, vous pouvez parcourir et, en toute confiance, supprimer tout le code inutile que vous aviez précédemment conservé `` au cas où '', etc. Je ne sais pas comment j'ai survécu sans contrôle de version.

  • Réduisez les infinis

Si quatre URL différentes pointent toutes vers la même ressource, le problème est bien plus important. Vous finissez par traiter une quantité infinie d'URL. Dès que vous le pouvez, assurez-vous que vous disposez d'une stratégie de normalisation des URL. Une fois cela fait, vous pouvez commencer à attacher des significations sémantiques aux URL et pouvoir effectuer des recherches inversées de la ressource vers l'URL. Cela vous permet de séparer «l'empreinte Web» des «ressources» du site.

Vous devez vous demander, "étant donné une URL, quelle est sa forme normalisée?". Une fois que vous l'avez épinglé. Ensuite, 50 000+ URL sur votre site peuvent être réduites, soit 2 000. ce qui est beaucoup plus facile à comprendre et à gérer dans votre esprit.

voir: http://www.sugarrae.com/be-a-normalizer-a-c14n-exterminator/

  • Commencez par modéliser «ce qui est», pas «ce que vous voulez que ce soit»

Si vous ranger un site hérité, qui n'a pas été conçu avec les meilleures pratiques à l'esprit dès le départ, alors il est tentant de passer de `` désordre '' à `` la conception idéale ''. Je crois que vous devez le faire en au moins deux étapes: «mess» -> «code hérité bien modélisé» -> «nouveau code idéal avec des fonctionnalités supplémentaires». Arrêtez d'ajouter des fonctionnalités. Concentrez-vous sur la réparation du désordre ou l'encapsulation derrière une couche anti-corruption. Alors seulement, vous pourrez commencer à changer le design en quelque chose de mieux.

Voir: http://www.joelonsoftware.com/articles/fog0000000069.html

Voir: http://www.laputan.org/mud/

  • La tester est une bonne idée.

Créez une suite / infrastructure de test et commencez à ajouter des tests. Mais, il est assez difficile de tester un code hérité. Alors, ne vous y attardez pas trop. Tant que vous disposez du framework, vous pouvez ajouter des tests petit à petit.

Voir: http://www.simpletest.org/en/web_tester_documentation.html

  • Ayez du courage dans vos convictions

La plupart des publications sur les meilleures pratiques de développement de logiciels sont centrées sur les ordinateurs de bureau / entreprises. Pendant que votre site est en désordre, vous lisez ces livres et vous pouvez être impressionné par la sagesse qui s'en dégage. Mais n'oubliez pas que la plupart de ces meilleures pratiques ont été accumulées bien avant que le Web / SEO ne devienne important. Vous en savez beaucoup sur le Web moderne, plus que ce qui est mentionné dans les livres classiques comme POEA, Gof etc. Il y a beaucoup à tirer d'eux, mais ne jetez pas complètement votre propre expérience et vos connaissances.


Je pourrais continuer. Mais ce sont des choses que j'ai choisies lors de la refonte d'un ancien site hérité en un nouveau brillant.

JW01
la source
De bons liens de référence!
Nilesh
2

Avant de faire quoi que ce soit, il est préférable d'avoir votre projet en contrôle de code source. De cette façon, vous pouvez annuler des modifications ou travailler sur des modifications majeures sur une branche distincte, ainsi que sur des jalons de balises.

Ensuite, écrivez des tests pour tout code que vous prévoyez de modifier. Vous n'avez pas besoin de tout faire en même temps, d'écrire des tests pour tout. Exactement ce sur quoi vous prévoyez de travailler immédiatement. La théorie veut que, avec suffisamment de temps, la majeure partie de la base de code sera couverte par des tests. Notez que certains refactorings sont «sûrs» de se passer de tests - ceux-ci sont documentés dans le livre Legacy Code mentionné précédemment, et sans doute ailleurs.

Avec des tests en place pour une section de code, modifiez le code. Faites tout ce que vous devez, tant que les tests réussissent.

Même avec le code hérité, vous pouvez effectuer TDD si vous effectuez des ajouts ou des modifications. Écrivez d'abord des tests pour vos modifications anticipées, voyez-les échouer, puis effectuez les modifications.

Certains outils peuvent être utiles ici. NDepend peut signaler du code fortement couplé et d'autres odeurs. NCover suit vos niveaux de couverture de code. FxCop est essentiellement un vérificateur d'exactitude de code, au-delà de ce que fait le compilateur. Ce sont tous des outils utiles à avoir à portée de main pour un projet de toute taille réelle, en particulier la variété héritée.

En fin de compte, c'est un processus en plusieurs étapes. N'essayez pas de tout faire en même temps, prenez-le un peu à la fois.

Grant Palin
la source
-2

Si c'est assez moche pour me faire chier, c'est assez moche pour moi de supprimer le tout et d'écrire une goutte en remplacement.

Vous constaterez que plus souvent qu'autrement, cela prend le même temps que de le faire, de rester assis là et de garder la pointe des pieds autour d'un gâchis non organisé et sans papiers et de le caresser doucement.

Sneakyness
la source
2
Je ne suis pas d'accord (même si je ne vous ai pas donné -1). joelonsoftware.com/articles/fog0000000069.html
JW01
1
C'est vraiment trop une décision situationnelle de me défendre avec précision. Je ne pourrais pas faire cela quand je travaille sur une bibliothèque Objective-C massive, cependant, je n'ai aucun scrupule à écrire une bibliothèque javascript entièrement nouvelle.
Sneakyness
Très mauvaise idée! J'aimerais avoir lu l'article de Joel Spolsky auquel @ JW01 était lié il y a 2 ans avant de décider de réécrire une application PHP existante en utilisant Angular & Bootstrap. Angular & Bootstrap sont d'excellentes technologies, mais j'essaie TOUJOURS de convertir cette ancienne application 2 ans plus tard. J'aurais dû juste modifier l'application existante et ne pas avoir arraché / remplacé.
Zack Macomber du
Je suis d'accord surtout lors de la prise en compte de votre commentaire. "scénario" est l'élément clé qui détermine une décision. Devriez-vous arracher cette énorme API qui sert l'ensemble de votre entreprise? Qui sait, il y a beaucoup à considérer. Vous voudriez des tests avant de tester après. L'article lié à est trop linéaire, comme s'il y avait une taille unique, mais qu'en est-il quand quelque chose est bogué ou est vraiment du vieux code? L'article suggère-t-il vraiment que nous ne quittons pas l'héritage avec un code plus récent plus facile à lire et à maintenir? Il n'y a pas de noir et blanc dans le monde du développement, juste des scénarios et des décisions
James