Des articles approfondis sur les technologies qui façonnent l'avenir.

Pourquoi un bon logiciel demande du temps

Pourquoi les meilleurs projets logiciels prennent des années, pas des mois. Plaidoyer pour la patience, de l'open source aux startups.

Un bonsaï soigneusement taillé poussant hors d'un ordinateur portable ouvert sur une table en bois

Flask a mis huit ans pour atteindre la version 1.0. SQLite est en développement actif depuis 2000 et continue de recevoir des améliorations significatives. Le noyau Linux a plus de trois décennies et gagne sans doute en qualité avec l'âge. Pendant ce temps, on attend d'une startup financée par du capital-risque qu'elle montre sa traction en 18 mois, ou qu'elle explique pourquoi elle ne le fait pas.

Il existe un décalage croissant entre le temps que demande réellement la construction d'un bon logiciel et celui que nous lui accordons. La pression pour livrer vite n'est pas fondamentalement mauvaise, mais elle crée une culture où la patience passe pour un manque d'ambition, et où les projets qui durent sont qualifiés de « lents » pendant les années où ils corrigent silencieusement le tir.

Le mythe du succès du jour au lendemain

Presque tous les « succès du jour au lendemain » dans le logiciel ont une longue histoire derrière eux. React a été utilisé en interne chez Facebook pendant plus d'un an avant d'être publié en open source. Rust a passé sept ans en développement avant d'atteindre la version 1.0. PostgreSQL a commencé comme projet de recherche en 1986 et n'est devenu la base de données de production incontournable que dans les années 2010, soit près de 30 ans d'amélioration discrète et constante.

Ce qui ressemble à une émergence soudaine résulte généralement d'améliorations qui se cumulent jusqu'à franchir un seuil de visibilité. Le logiciel s'améliorait en permanence. Les gens n'y prêtaient simplement pas attention jusqu'à ce qu'il devienne suffisamment bon pour être incontournable.

Armin Ronacher, le créateur de Flask, en a parlé directement. Flask a commencé comme une blague du 1er avril en 2010. Il est devenu un projet sérieux presque par accident. Des années de travail incrémental (corriger des cas limites, améliorer la documentation, repenser les API) en ont fait l'un des frameworks web Python les plus populaires. Aucune de ces années n'a été perdue. Chacune a renforcé les fondations.

Pourquoi le logiciel comporte une part de temps incompressible

Certains problèmes ne se résolvent pas plus vite en ajoutant des personnes ou en travaillant davantage. Fred Brooks l'a identifié en 1975 avec The Mythical Man-Month, et l'idée centrale n'a pas changé : certains aspects du développement logiciel sont séquentiels et ne se parallélisent pas.

  • Comprendre le domaine du problème. On ne saisit pleinement un espace de problèmes qu'après y avoir vécu un moment. La première version de tout logiciel encode vos hypothèses initiales. La deuxième encode ce que vous avez appris de la première. Une vraie compréhension demande des itérations, et les itérations demandent du temps.
  • Conception et stabilité des API. Les bonnes API émergent de l'usage. On ne conçoit pas une API parfaite dans le vide : il faut de vrais utilisateurs qui butent sur de vrais cas limites. Les bibliothèques qui se précipitent vers la 1.0 regrettent souvent leurs premiers choix de conception pendant des années.
  • Cas limites et durcissement. Les 80 % premiers d'une fonctionnalité prennent 20 % du temps. Les 20 % restants (cas limites, gestion des erreurs, particularités des plateformes) prennent les 80 % de temps restants. Ce ratio n'a rien de paresseux : c'est la nature même de la fiabilisation d'un logiciel.
  • Communauté et écosystème. Un outil n'est vraiment utile qu'une fois qu'il dispose de documentation, de tutoriels, de plugins et d'une communauté qui répond aux questions. Cet écosystème ne se fabrique pas : il pousse organiquement avec le temps.

Les dégâts de l'urgence artificielle

« Move fast and break things » était une devise raisonnable pour un réseau social qui cherchait son adéquation produit-marché. C'est une philosophie désastreuse pour l'infrastructure, les outils de développement, les bases de données, ou tout ce dont dépendent les systèmes d'autres personnes. Quand on précipite un logiciel fondamental, les casses s'accumulent.

J'ai vu plusieurs projets open source prometteurs s'effondrer parce qu'ils tentaient de grandir plus vite que leurs fondations ne pouvaient le supporter. Le schéma est prévisible : un projet devient populaire, les mainteneurs subissent la pression de livrer des fonctionnalités rapidement, la qualité baisse, les contributeurs s'épuisent et les utilisateurs migrent vers une solution plus stable. L'ironie, c'est que ralentir les aurait menés plus loin.

Les projets qui durent ne sont pas ceux qui ont livré le plus vite. Ce sont ceux qui ont pris de bonnes décisions assez tôt pour ne pas avoir à tout réécrire plus tard.

La dette technique ne se limite pas à du code désordonné. Elle tient aux décisions prises sous pression de temps, qui restreignent les possibilités futures. Chaque raccourci pris pour livrer plus vite est une taxe sur chaque changement à venir. Certains raccourcis valent le coup, mais il faut les prendre délibérément, et non parce que quelqu'un a décidé arbitrairement que la date limite tombe mardi prochain.

À quoi ressemble la patience en pratique

La patience dans le développement logiciel ne signifie pas avancer lentement pour le plaisir. Elle consiste à être délibéré sur ce que l'on construit et honnête sur la durée réelle des choses. Quelques schémas que j'ai vus fonctionner à merveille :

  • Livrer tôt, mais s'engager lentement. Mettez votre logiciel à disposition des utilisateurs rapidement pour recueillir des retours, mais soyez très prudent sur ce que vous engagez comme API stable. Utilisez généreusement le versionnement 0.x. Indiquez clairement que les choses peuvent changer.
  • Dire non aux fonctionnalités. Chaque fonctionnalité ajoutée est une fonctionnalité que vous maintiendrez éternellement. Les meilleurs projets ont un périmètre affirmé. SQLite liste explicitement ce qu'il ne fera jamais, et c'est cette discipline qui en fait la base de données la plus déployée au monde.
  • Investir dans les fondamentaux. Documentation, tests, messages d'erreur, performances : rien de tout cela n'est spectaculaire, mais tout cela se cumule. Un projet bien documenté, doté d'une solide suite de tests, peut avancer plus vite la troisième année qu'un projet mal documenté la première année.
  • Préserver l'énergie des mainteneurs. L'épuisement est le principal tueur des projets open source. Un rythme soutenable compte plus que la vélocité de sprint. Un mainteneur qui travaille 20 heures concentrées par semaine pendant cinq ans livre davantage que celui qui travaille 80 heures par semaine pendant six mois avant de disparaître.

Le piège de la vitesse des startups

Les startups sont confrontées à une tension légitime : il leur faut aller vite pour survivre, mais aller trop vite crée des systèmes fragiles qui deviennent un handicap à mesure qu'elles grandissent. Les entreprises qui s'en sortent bien tendent à distinguer deux types de vitesse.

La vitesse d'itération : la rapidité avec laquelle vous testez des idées, recueillez les retours des utilisateurs et changez de cap. Elle doit être maximisée. Cycles courts, prototypage rapide, acceptation de jeter des choses.

La vitesse d'engagement : la rapidité avec laquelle vous figez les décisions d'architecture, les API publiques et les modèles de données. Elle doit être minimisée. Gardez les choses réversibles aussi longtemps que possible. Plus vous pouvez différer les décisions irréversibles, plus vous disposerez d'informations au moment de les prendre.

L'erreur la plus courante des startups est de confondre les deux. Elles s'engagent sur des architectures aussi vite qu'elles itèrent sur les fonctionnalités, puis passent les deux années suivantes à payer la taxe de décisions prématurées.

Tirer les leçons des projets qui ont duré

Les projets logiciels sur lesquels nous nous appuyons le plus partagent un trait commun : à un moment, ils ont tous été jugés « lents ». PostgreSQL était le choix sage tandis que MySQL était l'option rapide et désinvolte. Python était « trop lent » alors que Perl était le choix pragmatique. Git a mis des années à devenir utilisable par des humains ordinaires.

Ce que ces projets avaient en commun, c'était du temps : le temps de faire des erreurs, d'en tirer des leçons et de bâtir quelque chose de solide. Ils n'essayaient pas d'être tout pour tout le monde dès la première année. Ils cherchaient à exceller dans leur objectif principal, et acceptaient que cette excellence prenne le temps qu'il fallait.

La prochaine fois que vous serez frustré qu'un projet « prenne trop de temps », gardez en tête que ce sur quoi vous comptez le plus (votre système d'exploitation, votre base de données, votre runtime de langage, votre gestionnaire de versions) a pris plus de temps que quiconque ne l'avait prévu. Et c'est précisément pour cela que ça fonctionne.

Certaines choses prennent simplement du temps. La meilleure réponse n'est pas de lutter contre cette réalité, mais de construire des systèmes, des équipes et des attentes qui en tiennent compte.