Librairie vs. framework
Jouons un peu :
- React : librairie ou framework ? ➡️ Librairie.
- Jest : librairie ou framework ? ➡️ Framework.
- Express : librairie ou framework ? ➡️ Framework.
Si cela vous laisse perplexe, lisez la suite.
Une affaire de taille ? Hmmm, pas vraiment. Il y a des petits frameworks et de très grosses libraires. Et puis, bon, la taille… enfin, vous savez.
Alors quoi ?
Wikipedia suggère qu'un "framework se distingue d'une simple bibliothèque logicielle principalement, d'une part par son caractère générique, faiblement spécialisé, contrairement à certaines bibliothèques ;" (non, je n'ai pas tronqué cette phrase). Une fois que vous aurez remis les mots dans l'ordre, vous conviendrez avec moi que le fond est contestable. Les contre-exemples sont légion, à commencer par React, une librairie absolument pas spécialisée.
Plus loin, le même article énonce que "[le framework] impose un cadre de travail guidant l'architecture logicielle voire conduisant le développeur à respecter certains patrons de conception". Alors ça, oui, et nous allons y revenir.
D'ailleurs, revenons-y tout de suite.
Effectivement, ce qui caractérise un framework, c'est l'inversion de contrôle. Cette fois-ci, Wikipedia fait du bon boulot pour définir la chose :
L’inversion de contrôle [...] fonctionne selon le principe que le flot d'exécution d'un logiciel n'est plus sous le contrôle direct de l'application elle-même mais du framework ou de la couche logicielle sous-jacente.
Sachez que quand vous passez un casting à Hollywood ou un entretien d'embauche à Issy-Les-Moulineaux, vous faites de l'inversion de contrôle sans le savoir #MonsieurJourdain : "Ne nous appelez pas, c'est nous qui vous appellerons".
Mais je conçois que cela puisse rester abstrait, alors prenons un exemple très simple créé pour l'occasion :
https://github.com/mathieueveillard/library-vs-framework
Un test runner rudimentaire, sous forme de librairie. 2 méthodes, expectEqual
et display
, appelables comme suit :
display("This test succeeds", expectEqual(0, 0));
Mais on peut trouver dommage d'exposer ainsi les entrailles de la librairie, car cela requiert que moi, développeur, j'aie déjà une certaine compréhension de son fonctionnement.
D'où l'idée de créer un framework "au-dessus" de la librairie, c'est-à-dire utilisant cette dernière. Le framework, bien que microscopique, a tout d'un grand car il met en œuvre l'inversion de contrôle. Pour aller au bout de l'exercice, nous décidons de passer la fonction expect en argument au scénario de test :
test("This test succeeds", (expect) => { expect(0, 0); });
Au final, pourquoi créer un framework plutôt qu'une librairie ?
Un framework est là pour vous tracer la voie, pour vous permettre d'avancer sans vous demander sans cesse où aller : la direction vous est imposée. Très utile pour mettre le pied à l'étrier à des personnes moins expérimentées et vous permettre de produire en quelques dizaines de minutes un résultat robuste et de qualité. Cela explique notamment le succès d'AngularJS en entreprise, à une époque (~2010) où presque personne dans l'industrie du logiciel ne possédait les compétences nécessaires pour coder proprement une Single Page Application.
Le corollaire est qu'il est difficile de s'écarter du chemin déjà tracé. À la longue, les développeurs les plus expérimentés peuvent se sentir bridés, voire être contraints de développer des rustines pour pallier les limitations du framework. Raison pour laquelle, à la longue, React a regagné des parts de marché.
Les frameworks se justifient pleinement dans certains cas — je pense en particulier à Jest. Mais on le sait, il ne faut pas abuser des bonnes choses (conseil de grand-père Mathieu).