Blog

Réutilisation et recyclage

Thierry Chatel • 11 août 2011

21 juillet 2011, la navette spatiale américaine Atlantis se pose pour la dernière fois sur la piste de Cap Canaveral, mettant un terme à un programme de 30 ans d'exploitation des navettes. Si les images sensationnelles ont bercé notre imaginaire, l'échec économique dudit programme nous rappelle que dans des domaines technologiques tout comme en informatique, réutiliser peut souvent être très coûteux.

Navette spatiale, le vrai coût du réutilisable

C'est l'exemple type d'un programme ambitieux où la réutilisation est l'objectif premier, dans une volonté de réduction des coûts.

L'idée est simple sur le papier, au point qu'elle semble évidente. On se doute bien qu'il revient moins cher de réutiliser un avion plutôt que de le jeter à chaque fois et d'en acheter un nouveau pour le prochain vol. Les fusées à usage unique, c'est dépassé, qui irait jeter sa voiture lorsque le réservoir est vide ? Donc à l'évidence, si l'on arrive à concevoir un engin réutilisable pour la mise en orbite des satellites, il permettra d'énormes économies. Un bel exemple de fausse bonne idée.

Pourtant c'est dans cette optique qu'est étudié et développé le programme américain de navette spatiale, avec l'ambition de permettre la mise en orbite basse de satellites pour seulement une fraction du coût d'une fusée à usage unique.

La réalité s'est avérée très différente. Au delà du coût faramineux du développement des navettes, elles ont souffert de gros problèmes de fiabilité et de sécurité, mis en évidence par les deux accidents que l'on sait, et nécessité avant chaque nouveau vol une maintenance lourde et coûteuse.

Au final, le coût d'un vol de navette a atteint 450 millions de dollars, pour le seul coût d'exploitation, soit le prix de quatre fusées russes Proton. Pire encore, la prise en compte du développement du programme et de la construction des navettes fait grimper le coût à 1,5 milliard de dollars par vol. C'est ainsi que le coût de mise en orbite basse de satellites par la navette a été estimé à environ 60 000 $/kg, à comparer aux 5 000 $/kg d'une fusée Proton, pourtant de conception plus ancienne.

Comment un programme destiné à réduire de façon drastique le coût de mise en orbite grâce à du matériel réutilisable a-t-il pu réussir à le multiplier par douze ? Il faut croire que la réutilisation n'est pas toujours aussi économique que ce qu'on pourrait l'imaginer. L'extrême complexité du système de navettes a entraîné une mise au point et une maintenance très coûteuses, alors même que sa fiabilité n'a jamais vraiment pu être assurée.

Optique de réutilisation : la quête de la généricité

En informatique aussi cette tentation de l'outil générique réutilisable est très répandue, sans doute bien plus encore que dans des domaines technologiques où les contraintes de production imposent généralement un minimum de pragmatisme.

On constate que la plupart des développeurs ont tendance à vouloir créer des outils réutilisables chaque fois que c'est possible, sans se demander si c'est utile. Ils raisonnent systématiquement en terme d'API ou de modules génériques, et reconnaissent immédiatement la possibilité de résoudre un besoin immédiat par un outil plus général qui sera susceptible de répondre à d'autres besoins similaires. C'est une tendance naturelle, acquise pendant les études et renforcée ensuite en travaillant avec d'autres qui ont le même réflexe.

Mais les pronostics sur des besoins futurs s'avèrent rarement exacts, le plus souvent soit ces besoins ne se présenteront pas, soit ils se présenteront sur une forme différente de celle qui avait été anticipée. Du coup l'outil qui se voulait générique ne resservira pas, ou devra être largement modifié pour pouvoir resservir. C'est pourquoi le surcoût induit par le fait de faire un outil plus général, par rapport à la simple résolution du besoin immédiat, sera en pratique rarement rentabilisé.

Or ce surcoût est loin d'être neutre. Développer une API ou un module externe qui soit générique et fiable, suffisamment testé et documenté, va demander beaucoup de travail. Ce sera souvent quelque chose de bien plus complexe qu'une solution directe au problème immédiat, et cette complexité rendra aussi la maintenance et les évolutions plus délicates et plus coûteuses. C'est un choix qui est souvent fait sans être suffisamment réfléchi, sans avoir vraiment conscience du surcoût réel qu'il implique, simplement parce que ça semble a priori être généralement une bonne idée de faire quelque chose qui pourra resservir. C'est un réflexe dont il faut se méfier, car la réalité est rarement conforme à cette fausse impression, et il entraîne souvent de mauvais choix.

C'est pourquoi l'une des valeurs mises en avant par la méthode Extreme Programming est la simplicité, sous la forme d'un principe exprimé en anglais par "You ain't gonna need it", c'est-à-dire "Vous n'en n'aurez pas besoin". L'idée est de ne jamais développer des éléments dont on aura besoin, parce que le plus souvent on n'en n'aura pas besoin, ou pas sous cette forme. Il faut développer uniquement ce dont on a déjà besoin, sans spéculer sur l'avenir, en implémentant des solutions simples qu'on pourra facilement faire évoluer quand se présenteront de nouveaux besoins concrets et clairement identifiés. Il sera bien plus facile de faire évoluer une solution simple, plutôt qu'une implémentation complexe prévue pour prendre en compte des besoins hypothétiques, lorsque ces nouveaux besoins se présenteront sous une forme différente de celle imaginée.

Ce n'est pas un aspect qui se limite à l'écriture du code, tous les acteurs de la réalisation d'un projet informatique sont concernés, développeurs, architectes, chefs de projets, y compris les clients. La qualité de la réalisation progressera lorsqu'ils s'efforceront de concevoir et de développer des solutions simples plutôt que de céder au mauvais réflexe de vouloir faire générique.

Recyclage a posteriori : l'illusion de la facilité

Il existe une autre tentation qui peut être dangereuse, celle-ci plus présente chez les décideurs que chez les développeurs, c'est de vouloir réduire les coûts en recyclant du code déjà écrit pour un projet similaire. Les développeurs y sont moins enclins car ils ont tous un jour ou l'autre été confrontés à la difficulté de l'exercice.

Tout va dépendre en fait de l'ampleur des différences entre le projet pour lequel le code a été écrit et celui auquel il faut l'adapter. Et bien sûr aussi de la qualité du code récupéré, de sa complexité, et du fait qu'il y ait ou non une couverture complète de ses fonctionnalités par des tests unitaires. Il est bien plus compliqué d'adapter un code existant à de nouvelles fonctionnalités que d'implémenter ces mêmes fonctionnalités dans un outil complètement nouveau, qui n'est pas basé sur un ancien code. Or on a facilement tendance à imaginer gagner du temps en recyclant le code d'un ancien projet, en ne tenant pas compte du fait que le développement de toutes les nouvelles fonctionnalités sera pénalisé par l'existant auquel il faudra les intégrer. Il ne faut pas négliger non plus le fait que les modifications sur l'ancien code seront généralement effectuées par d'autres personnes que celles qui l'avaient développé à l'origine, et plus sa qualité laisse à désirer, plus ces personnes auront du mal à maîtriser l'ancien code, à le faire évoluer sans en dégrader le design ou la fiabilité.

Faire évoluer du code existant pour répondre à un besoin similaire mais un peu différent de celui pour lequel il a été conçu, ça peut être à la fois risqué et coûteux. Sans une bonne couverture des fonctionnalités par des tests unitaires, il sera très difficile d'assurer la fiabilité du code résultant de ce recyclage. Il faut que les fonctionnalités à conserver fonctionnent toujours correctement et sans bug, de même que les nouvelles. Il est souvent difficile d'anticiper ou de déceler tous les impacts des modifications apportées au code réutilisé. Il est impératif aussi d'effectuer tout le refactoring nécessaire pour que le résultat ne ressemble pas à un monstre de Frankenstein informatique, assemblage inélégant et mal intégré d'anciennes fonctionnalités et de nouvelles. S'il n'est pas possible en recyclant le code d'un ancien projet d'arriver au niveau de qualité d'un code nouvellement écrit, alors ça posera forcément des problèmes de fiabilité et surtout de coût de maintenance, aussi bien corrective qu'évolutive. S'il est malheureusement fréquent de voir la qualité se dégrader au cours de la réalisation d'un projet par manque de refactoring du code, le risque est encore bien plus élevé lorsqu'il s'agit de recycler du code existant.

Recycler du code, c'est quelque chose qui doit être limité aux très rares occasions où l'opération sera bénéficiaire. Que le nouveau projet soit similaire à l'ancien n'est pas suffisant. S'il est identique à quelques détails près, alors la question peut se poser, et doit être étudiée de façon approfondie avant la prise d'une telle décision. Si les modifications à apporter impactent trop le code existant, alors son recyclage coûtera bien plus cher qu'un nouveau développement, pour sans doute une qualité finale nettement inférieure.

Pour revenir à l'analogie spatiale, il est avéré que la perte de la première fusée Ariane 5 a été causée par le recyclage mal effectué et mal fiabilisé d'un programme écrit pour Ariane 4. En l'occurrence une défaillance s'est produite dans le code d'un module du système de contrôle de vol. Ironie de l'histoire, ce module n'aurait même pas dû être présent sur Ariane 5 car il correspondait à une possibilité de réinitialisation rapide du compte à rebours de décollage qui n'existait plus sur cette nouvelle version de la fusée. Un excès de confiance a poussé à croire que ce qui était largement testé et validé sur Ariane 4 fonctionnerait sur Ariane 5. C'est donc un simple recyclage de code mal avisé qui aura causé la perte de la fusée, et entraîné une année de retard sur la suite du programme Ariane.

C'est pourquoi il vaut mieux oublier l'idée simpliste et généralement erronée selon laquelle la réutilisation de code fait gagner du temps et de l'argent. Il vaut mieux s'appuyer sur le précepte des méthodes agiles et réaliser une solution simple répondant seulement au besoin identifié, et ne recycler un programme issu d'un autre projet que si les différences sont réellement minimes.

Derniers billets

11 juin 2012

Avenir des applications web RIA

Ou la percée des frameworks clients JavaScript dans le développement d'applications web.

5 avril 2012

Exemples d'utilisation du framework AngularJS

Voici les fichiers des exemples que j'ai montrés lors de ma présentation du framework AngularJS à Montpellier.

15 mars 2012

AngularJS, énième framework JavaScript ou pierre angulaire des applications web ?

Un nouveau framework qui révolutionne l'écriture de clients web, et destiné à connaître un gros succès.

6 septembre 2011

Informatisation des processus et facteur humain

Ou quels sont les inconvénients du déterminisme induit par l'informatisation, et comment les éviter au maximum ?

26 août 2011

Ergonomie des applications web et productivité

Quelles fonctionnalités plus ou moins courantes sur internet peuvent être adoptées avec succès dans des applications de gestion, pour permettre un travail plus efficace ?

11 août 2011

Réutilisation et recyclage

Que peut-on apprendre de la navette spatiale américaine à propos de la réutilisation de code en informatique ?

Flux

Atom