Chapitre 1 - Tirez parti des paradigmes de programmation

Une couple regardant la mer

Le concept de paradigme en programmation

Connaissez-vous d’où vient le terme “paradigme” et sa signification ? Le mot paradigme tire ses origines du mot Grec “paradeigma”. Ce terme se traduit par “schéma”, “modèle” ou “exemple”. Selon le dictionnaire Larousse, un paradigme est “un modèle théorique de pensée qui oriente la recherche et la réflexion scientifiques”. Pour le coup, j’aime assez cette définition.

En effet, un paradigme, c’est une façon de voir le monde. C’est exactement comme un courant de pensée. Vous avez des règles et des principes à respecter, ou au moins, à suivre. En informatique, les choses ne sont pas si éloignées.

On appelle un “paradigme de programmation” une approche visant à structurer et organiser le code afin de résoudre des problèmes. Ici, il faut bien voir que le mot “problème” signifie “un cas d’usage” ou “un ensemble de fonctionnalités”. Par exemple, comment gérer la communication de différents sous-systèmes d’un programme ou comment gérer le contenu dynamique d’un site web. Ces deux exemples sont des problèmes traditionnels que nous rencontrons tous lorsque nous développons des applications. De nombreux ingénieurs ont donc réfléchi à ces problèmes et proposé des solutions. Ce sont les fameux paradigmes de programmation.

Chaque paradigme a son propre vocabulaire et ses propres méthodologies de résolution de problème. Vous le verrez dans les deux prochaines parties. Quand vous décidez d’utiliser un paradigme, vous adoptez donc sa façon de penser et vous vous pliez à ces règles. Vous ne pourrez pas toujours respecter ces règles à 100 %, c’est le fameux “modèle théorique” de la définition du Larousse. Cela dit, ce modèle a l'avantage de vous donner un cadre de référence et facilite souvent la collaboration en équipe. Les paradigmes ont aussi pour objectif de créer une compréhension commune au sein d'une équipe. Ils réduisent ainsi les risques de confusion ou de malentendus quant aux attentes, aux méthodes et aux responsabilités.

Sachez qu’il existe de nombreux paradigmes de programmation tels que la programmation impérative, la programmation déclarative, la programmation orientée objet, la programmation fonctionnelle, etc.

Dans ce cours, on va se focaliser sur la programmation orientée objet et la programmation fonctionnelle. N’hésitez pas à me dire si les autres paradigmes vous intéressent et je regarderai comment les incorporer dans ma “roadmap”. 

Dernier point : est-ce que les patrons de conception, ou design pattern en anglais, sont des paradigmes de programmation ? La réponse est non. Bien qu’ils soient liés au développement logiciel et à la résolution de problèmes, ces deux concepts opèrent à des niveaux différents.

Quand ils sont bien expliqués, les design patterns sont des solutions réutilisables pour résoudre des problèmes communs. Ils définissent, par exemple, comment les objets sont censés communiquer entre eux. Les paradigmes de programmation se concentrent sur une partie plus abstraite et définissent comment un programme est architecturé dans son ensemble.

Une route de campagne en pixel art

Pourquoi existe-t-il plusieurs approches ?

C’est une question assez intéressante qui vaut la peine d’être posée. Pourquoi ne nous sommes-nous pas contenter d’une seule approche ? Il y a plusieurs réponses à cette question. Pour faire simple, c’est principalement due à la nature diverse des problèmes rencontrés ainsi qu’aux manières d’aborder et de résoudre ces problèmes. On va prendre quelques exemples.

Si vous avez des problématiques telles que des calculs mathématiques ou de la transformation de données, vous aurez tendance à utiliser la programmation fonctionnelle. Je n’ai pas forcément envie de rentrer trop dans le détail tout de suite mais sachez que c’est en rapport avec la fameuse gestion de l’état (la mutabilité). Je reviens sur cette notion un peu plus bas dans ce chapitre.

D'un autre côté, vous aurez tendance à utiliser la programmation orientée objet lors de la modélisation de systèmes complexes. Le framework NestJS par exemple, un framework back-end JavaScript/TypeScript, utilise la programmation orientée objet. Ça fait assez sens quand on y pense. Un backend embarque souvent de nombreux sous-systèmes tels que la communication avec des bases de données, des systèmes de cache et des règles d’autorisation. Le choix d’un paradigme de programmation se fait le plus souvent en fonction des contraintes.

Aucun paradigme n’est supérieur à un autre. Finalement, c’est comme les langages de programmation. Certains langages sont plus adaptés pour faire de la statistique, le R par exemple, et d’autres, tels que le Php ou le Ruby, plus pour faire des sites webs. Parfois, la décision concernant le paradigme viendra du langage. Le Java et le C++ sont des langages orientés objets et l’Haskell et l’Elixir sont des langages issus de la programmation fonctionnelle. Vous n’aurez pas le choix.

Mais alors, quid du JavaScript ? Pour le coup, avec le JavaScript, vous pouvez faire les deux. Cela est d’autant plus vrai si vous programmez en TypeScript. Le TypeScript intègre des concepts de classes abstraites et d’interfaces que le JavaScript n’a pas par défaut. Idem côté programmation fonctionnelle où des librairies orientée programmation fonctionnelle existent. Tout au long du cours, nous verrons ensemble des aspects du TypeScript liés à ces deux paradigmes de programmation.

Pour approfondir ces idées et comprendre les débats en cours dans le domaine, je vous conseille cette excellente vidéo intitulée “Why Software Engineers disagree about everything”. Elle va vous permettre de prendre un peu de hauteur par rapport à tous les concepts et opinions abordées dans ce cours.

Il est maintenant temps de parler d’état.

Des verres d'eau en pixel art

La gestion de l’état, concept central de ces paradigmes

L’état est un concept central en programmation. On définit un état comme des informations gardées en mémoire par l’ordinateur. C’est quelque chose qui n’est pas très éloigné de l’état d’un être humain. Prenons un exemple.

On parle souvent de notre état de fatigue. En fonction de divers paramètres, notre état de fatigue peut être plus ou moins élevé. Si vous avez, par exemple, passé une mauvaise nuit ou si vous n’avez pas pris de vacances depuis longtemps, votre état de fatigue pourra être plus élevé. Vous allez pouvoir réaliser des actions qui vont mettre à jour cet état, par exemple, en faisant une sieste, en buvant du café ou en prenant des vacances.

En programmation, on va parler d’état dans la gestion d’une connexion à une base de données par exemple. Cette gestion pourra avoir différents états tels que “connecté”, “en cours de connexion”, “déconnecté”, etc.

En fonction de l’état de votre application, le code qui sera exécuté ne sera pas forcément le même. Ce qui est intéressant ici, c’est que la programmation fonctionnelle et la programmation orientée objet ne gèrent pas l’état de la même façon. Au cœur de cette gestion différente se trouve un concept central. La mutabilité.

Je vous invite à faire une recherche sur le concept de mutabilité. Qu’est-ce que ça veut dire ? Si cela peut vous aider, vous pouvez aussi regarder son opposé. L’immutabilité.


Quelqu'un buvant un café - Pixel Art


En informatique, la mutabilité désigne la capacité d’une donnée à être modifiée après sa création. On parlera de données mutables, lorsque vous pourrez les modifier et les mettre à jour. On parlera de données immuables (ou immutables) lorsque vous ne pourrez pas modifier ces données.

Dans le cadre de la programmation orientée objet, on travaille, comme le nom l’indique, avec des objets. Ces objets stockent un état. Ils sont dits mutables parce que vous allez pouvoir modifier leur état au cours du cycle de vie du programme.

En programmation fonctionnelle, c’est le contraire. Vous ne pouvez modifier un état existant. Vous devez générer une nouvelle version de l’état. Si c’est la première fois que vous vous frottez à ces deux paradigmes, je sais que cela peut sembler encore assez abstrait. Ne vous inquiétez pas, vous verrez durant les deux prochaines parties des exemples concrets.

À l’heure actuelle, je vous demande simplement de vous souvenir des termes “mutabilité” et “immutabilité”.

  • La mutabilité autorise la modification de l’état d’une donnée.
  • L’immutabilité interdit la modification de l’état d’une donnée. Vous devez recréer une nouvelle version de cette donnée modifiée.


Un bon exemple ici qui peut faciliter votre compréhension est la méthode .map en JavaScript. Cette méthode est issue de la programmation fonctionnelle et s’utilise uniquement sur les tableaux. Son utilité est de réaliser des modifications sur un tableau existant. Cela dit, au lieu de modifier le tableau existant, en ajoutant ou en supprimant des données à l’intérieur, elle génère un nouveau tableau. Vous êtes face à de l’immutabilité.

Vous pouvez coller le code ci-dessus dans JSBin. Si vous l’exécutez, vous verrez que la méthode map utilisée sur le tableau numbers créé une nouvelle version du tableau numbers et l’assigne à la constante numbersByTwo. Vous voici face à de la programmation fonctionnelle.

Tout au long du cours, vous verrez que vous faites de la programmation fonctionnelle et orientée objet sans vraiment le savoir 🙂.

Quelqu'un lisant un livre dans une bibliothèque en pixel art

Approfondissez le concept de paradigme

Vous allez rapidement voir que les paradigmes de programmation sont souvent des sujets de débat. Certaines personnes préfèrent un paradigme de programmation plutôt qu’un autre. Mon conseil ici est de rester en dehors de ces débats.

Écoutez les arguments de chacun et renseignez-vous autant que possible sur le sujet. Pensez aussi à vous poser des questions. Par exemple, la prochaine fois que vous programmerez une API Rest. Demandez-vous si vous utilisez plutôt de la programmation fonctionnelle ou orientée objet. Ou un autre paradigme. Il est important de rester ouvert à différentes approches.

Posez-vous aussi ces questions quand vous utilisez un framework. J’ai parlé précédemment de NestJS. J’ai notamment dit qu’il utilisait la programmation orientée objet. Prenez le temps de l’essayer et d’aller un peu traîner sur son code source. Si ça peut vous “rassurer”, je reviendrai très bientôt sur ce framework 🙂.

Si vous voulez prendre un peu d’avance sur les prochaines parties, je vous invite à lire ces quelques ressources :


Quelqu'un vendant des journaux, pixel art

Résumé

  • Un paradigme de programmation est une approche visant à structurer et à organiser son code. Contrairement à des design patterns, qui servent à résoudre un problème précis, les paradigmes ont pour objectif de structurer le code dans son ensemble. Chaque paradigme a son propre vocabulaire et sa propre méthodologie.
  • En fonction des situations, vous serez amené à privilégier un paradigme plutôt qu’un autre. L’idée ici n’est pas de voir un paradigme comme supérieur à un autre mais plus de choisir le bon outil au bon moment. De mon point de vue, il est important de bien connaître la programmation orientée objet ET la programmation fonctionnelle.
  • La gestion de l’état au centre de ces deux paradigmes. Dans le cadre de la programmation orientée objet, on dit que l’état est mutable. Autrement dit qu’il peut être modifié / altéré. Dans le cadre de la programmation fonctionnelle, l’état est dit immutable. Il ne peut pas être modifié. Il doit être régénéré.
  • D’une manière générale, essayez de rester en dehors de ces “faux” débats sur quel paradigme est le meilleur. Soyez capable de choisir le bon outil au bon moment 🙂.


Passer au prochain chapitre