Bonjour, amis. En attendant le lancement du cours , nous partageons traditionnellement avec vous la traduction de matériel utile.
Le logiciel résout de plus en plus de tâches quotidiennes, tout en devenant de plus en plus complexe. Comme l'a dit un jour Marc Andreessen, il absorbe le monde.

En conséquence, au cours des dernières années, les approches de développement et de livraison d'applications ont considérablement changé. Ce furent des changements de portée tectonique, qui ont abouti à l'émergence d'un ensemble de principes. Ces principes se sont révélés utiles pour former une équipe, concevoir, développer et livrer votre application aux utilisateurs finaux.
Les principes peuvent être résumés de la manière suivante : l'application doit être petite, réseau et avoir une architecture axée sur le développeur. En vous basant sur ces trois principes, vous pouvez créer une application robuste et complète qui peut être livrée rapidement et en toute sécurité à l'utilisateur final, tout en étant facile à faire évoluer et à étendre.

Chacun des principes proposés a un certain nombre d'aspects que nous discuterons pour montrer comment chaque principe contribue à l'objectif final, qui est de livrer rapidement des applications fiables faciles à entretenir et à utiliser. Nous examinerons les principes en les comparant à leurs opposés, afin de clarifier ce que signifie, disons, «Assurez-vous d'utiliser le principe de petitesse».
Nous espérons que cet article vous incitera à utiliser les principes proposés pour construire des applications modernes, qui assureront une approche cohérente de la conception dans le contexte d'une pile technologique en constante expansion.
En appliquant ces principes, vous constaterez que vous suivez les dernières tendances en matière de développement logiciel, y compris l'approche au développement et à la livraison d'applications, l'utilisation de conteneurs (par exemple, ) et de frameworks pour l'orchestration de conteneurs (par exemple, ), l'utilisation de microservices (y compris l'Architecture Microservices et pour les applications microservices.
Qu'est-ce qu'une application moderne ?
Applications modernes ? Pile moderne ? Que signifie exactement «moderne» ?
La plupart des développeurs n'ont qu'une idée générale de ce qui compose une application moderne, il est donc nécessaire de définir clairement ce concept.
Une application moderne prend en charge plusieurs clients, qu'il s'agisse d'une interface utilisateur utilisant la bibliothèque JavaScript React, d'une application mobile sur Android ou iOS, ou d'une application qui se connecte à une autre via une API. Une application moderne implique un nombre indéfini de clients pour lesquels elle fournit des données ou des services.
Une application moderne offre une API pour accéder aux données et services demandés. L'API doit être immuable et constante, et non écrite spécifiquement pour une requête particulière d'un client donné. L'API est accessible via HTTP(S) et permet d'accéder à toute la fonctionnalité disponible dans l'interface graphique ou l'interface en ligne de commande.
Les données doivent être disponibles dans un format couramment accepté et compatible, tel que JSON. L'API fournit des objets et des services dans une forme compréhensible et organisée, par exemple, les API RESTful ou GraphQL offrent une interface adéquate.
Les applications modernes sont construites sur une pile technologique moderne, et une pile moderne est celle qui prend en charge ces applications. Cette pile permet au développeur de créer facilement une application avec une interface HTTP et des points de terminaison API clairement définis. L'approche choisie permettra à votre application d'accepter et d'envoyer des données au format JSON sans difficulté. En d'autres termes, la pile moderne correspond aux éléments du Twelve-Factor App. .
Les versions populaires de ce type de pile sont basées sur , , , , et . L'Architecture Microservices incarne un exemple de pile moderne implémentée dans chacun des langages mentionnés.
Notez que nous ne prônons pas exclusivement l'approche microservices. Beaucoup d'entre vous travaillent avec des monolithes qui doivent évoluer, tandis que d'autres s'attaquent à des applications SOA qui se développent et évoluent pour devenir des applications microservices. Certains se dirigent vers l'utilisation d'applications sans serveur, et quelques-uns implémentent des combinaisons des méthodes précédentes. Les principes énoncés dans cet article s'appliquent à chacun de ces systèmes avec quelques adaptations mineures.
Principes
Maintenant que nous avons une compréhension générale de ce qu'est une application moderne et d'un stack moderne, il est temps de plonger dans les principes d'architecture et de développement qui vous seront utiles dans la création, la mise en œuvre et la maintenance d'une application moderne.
Un des principes se résume à « créez des applications petites », appelons-le simplement le principe de petitesse. Il existe des applications incroyablement complexes composées de nombreux composants dynamiques. Par conséquent, construire une application à partir de petits composants discrets simplifie sa conception, son entretien et son utilisation en général. (Notez que nous avons dit « simplifie », et non « rend simple »).
Le deuxième principe est que nous pouvons augmenter la productivité des développeurs en les aidant à se concentrer sur les fonctionnalités qu'ils développent, tout en les libérant des soucis liés à l'infrastructure et au CI/CD lors de la mise en œuvre. En d'autres termes, notre approche est axée sur les développeurs.
Enfin, tout ce qui concerne votre application doit être connecté à un réseau. Au cours des 20 dernières années, nous avons fait de grands progrès vers un avenir réseau, car les réseaux sont devenus plus rapides et les applications plus complexes. Comme nous l'avons déjà établi, une application moderne doit être utilisée sur le réseau par de nombreux clients différents. L'application d'une pensée réseau dans l'architecture présente des avantages significatifs qui s'harmonisent bien avec le principe de petitesse et le concept d'approche, axée sur les développeurs.
Si, lors de la conception et de la mise en œuvre de votre application, vous gardez ces principes à l'esprit, vous bénéficierez d'un avantage indiscutable dans le développement et la livraison de votre produit.
Examinons ces trois principes plus en détail.
Le principe de petitesse
Il est difficile pour le cerveau humain de traiter simultanément une grande quantité d'informations. En psychologie, le terme charge cognitive désigne la quantité totale d'efforts mentaux nécessaires pour conserver des informations en mémoire. Réduire la charge cognitive des développeurs est primordial, car cela leur permet de se concentrer sur la résolution de problèmes, au lieu de garder en tête le modèle complexe actuel de l'application entière et des fonctionnalités en développement.

Les applications sont décomposées pour plusieurs raisons :
- Réduction de la charge cognitive des développeurs ;
- Accélération et simplification des tests ;
- Livraison rapide des modifications dans l'application.
Il existe plusieurs façons de réduire la charge cognitive des développeurs, et c'est ici que le principe de petitesse entre en jeu.
Donc, trois façons de réduire la charge cognitive :
- Réduire les délais que les développeurs doivent prendre en compte lors de la création d'une nouvelle fonctionnalité - plus le délai est court, moins la charge cognitive est élevée.
- Réduire le nombre de lignes de code sur lesquelles ils travaillent simultanément - moins de code signifie moins de charge.
- Simplifier le processus d'apport de modifications incrémentales à l'application.
Réduction des délais de développement
Retournons à l'époque où la méthodologie waterfall était la norme dans le processus de développement, et les délais de six mois à deux ans pour le développement ou la mise à jour d'une application étaient monnaie courante. En règle générale, les ingénieurs lisaient d'abord les documents pertinents, tels que le cahier des charges (PRD), la documentation système (SRD), le plan d'architecture, et commençaient à assembler toutes ces informations dans un seul modèle cognitif, selon lequel ils écrivaient du code. À mesure que les exigences et, par conséquent, l'architecture changeaient, il était nécessaire de déployer des efforts considérables pour informer toute l'équipe des mises à jour du modèle cognitif. Une telle approche pouvait, dans le pire des cas, paralyser le travail.
Le plus grand changement dans le processus de développement d'applications a été l'adoption de la méthodologie agile. L'une des caractéristiques principales de la méthodologie agile est le développement itératif. En conséquence, cela réduit la charge cognitive des ingénieurs. Au lieu d'exiger que l'équipe de développeurs réalise l'application en un seul cycle long, agile cette approche permet de se concentrer sur de petits volumes de code qui peuvent être rapidement testés et déployés, tout en obtenant également des retours. La charge cognitive d'une application est passée d'un délai de six mois à deux ans avec une multitude de spécifications à un ajout ou un changement de fonctionnalité de deux semaines, avec une compréhension plus floue d'une grande application.
Déplacer le focus d'une application massive vers de petites fonctions spécifiques, qui peuvent être terminées en un sprint de deux semaines, avec un regard tourné vers une seule fonction du prochain sprint, représente un changement significatif. Cela a permis d'accroître la productivité du développement tout en réduisant la charge cognitive, qui oscillait constamment.
Dans la méthodologie agile il est prévu que l'application finale sera une version quelque peu modifiée du concept initial, d'où le fait que le point final du développement est nécessairement ambigu. Seuls les résultats de chaque sprint spécifique peuvent être clairs et précis.
Petites bases de code
La prochaine étape pour réduire la charge cognitive consiste à réduire la base de code. En général, les applications modernes sont massives – une application d'entreprise fiable peut contenir des milliers de fichiers et des centaines de milliers de lignes de code. Selon l'organisation des fichiers, les relations et dépendances entre le code et les fichiers peuvent être évidentes ou, au contraire, obscures. Même le débogage de l'exécution du code peut poser des problèmes, selon les bibliothèques utilisées et dans quelle mesure les outils de débogage délimitent les bibliothèques/paquets/modules et le code utilisateur.
Construire un modèle mental opérationnel du code de l'application peut prendre un temps considérable, et à nouveau imposer une forte charge cognitive au développeur. Cela est particulièrement vrai pour les bases de code monolithiques, où il y a une grande quantité de code dont l'interaction entre les composants fonctionnels n'est pas clairement définie, et où la séparation des objets d'attention est souvent floue, car les frontières fonctionnelles ne sont pas respectées.
L'un des moyens efficaces de réduire la charge cognitive des ingénieurs est de passer à une architecture microservices. Dans l'approche microservices, chaque service se concentre sur un ensemble de fonctions ; le sens du service est généralement défini et clair. Les frontières du service sont également claires – gardez à l'esprit que la communication avec le service se fait via une API, donc les données générées par un service peuvent facilement être transmises à un autre.
L'interaction avec d'autres services est généralement limitée à quelques services utilisateurs et à quelques services fournisseurs, qui utilisent des appels API simples et clairs, par exemple via REST. Cela signifie que la charge cognitive sur l'ingénieur est sérieusement réduite. La tâche la plus complexe reste à comprendre le modèle d'interaction des services et comment des choses comme les transactions se déroulent entre plusieurs services. En fin de compte, l'utilisation de microservices diminue la charge cognitive en réduisant la quantité de code, en définissant des frontières claires pour le service et en assurant une compréhension des relations entre utilisateurs et fournisseurs.
Petites modifications incrémentales
Le dernier élément du principe petitesse – c'est la gestion des changements. Une tentation particulière pour les développeurs est de regarder la base de code (y compris, peut-être, leur propre code plus ancien) et de déclarer : « C'est nul, nous devons tout réécrire. » Parfois, c'est la bonne décision, parfois non. Cela impose à l'équipe de développeurs le fardeau d'un changement global de modèle, ce qui, à son tour, entraîne une charge cognitive massive. Il vaut mieux que les ingénieurs se concentrent sur les modifications qu'ils peuvent apporter durant le sprint, afin de déployer en temps voulu les fonctionnalités nécessaires, même progressivement. Le produit final doit ressembler à ce qui était initialement prévu, mais avec quelques modifications et des tests pour répondre aux besoins du client.
Lors de la réécriture de grandes portions de code, il est parfois impossible de livrer rapidement des modifications, car d'autres dépendances du système entrent en jeu. Pour contrôler le flux de changements, on peut utiliser la masquage de fonctionnalités (feature hiding). En gros, cela signifie que la fonctionnalité est présente en production, mais n'est pas accessible via des variables d'environnement (env-var) ou tout autre mécanisme de configuration. Si le code a passé tous les processus de validation, il peut se retrouver en production dans un état masqué. Cependant, cette stratégie ne fonctionne que si la fonction sera finalement activée. Dans le cas contraire, elle encombrera simplement le code et ajoutera une charge cognitive que le développeur devra gérer pour travailler de manière productive. La gestion des changements et les modifications incrémentales aident à maintenir la charge cognitive des développeurs à un niveau acceptable.
Les ingénieurs doivent surmonter de nombreuses difficultés même lors de l'implemendation de fonctionnalités supplémentaires simples. Du côté de la direction, il serait judicieux de réduire la charge inutile sur l'équipe afin qu'elle puisse se concentrer sur les éléments clés de la fonctionnalité. Voici trois choses que vous pouvez faire pour aider votre équipe de développement :
- Utiliser une méthodologie
agile, pour limiter le temps durant lequel l'équipe doit se concentrer sur les fonctions clés. - Réussir à réaliser votre application sous forme de plusieurs microservices. Cela limitera le nombre de fonctionnalités à mettre en œuvre et renforcera les frontières qui maintiennent la charge cognitive pendant le travail.
- Préférez les modifications incrémentales aux changements majeurs et encombrants, modifiez de petits morceaux de code. Utilisez le masquage de fonctionnalités pour implémenter des changements même s'ils ne seront pas visibles immédiatement après leur ajout.
Si vous appliquez le principe de la petitesse dans votre travail, votre équipe sera beaucoup plus heureuse, pourra mieux se concentrer sur la mise en œuvre des fonctionnalités nécessaires et aura plus de chances de déployer rapidement des changements de qualité. Cependant, cela ne signifie pas que le travail ne peut pas se compliquer ; au contraire, l'implémentation de nouvelles fonctionnalités peut nécessiter la modification de plusieurs services, et ce processus peut être plus complexe que dans une architecture monolithique. Quoi qu'il en soit, les avantages du principe de petitesse en valent la peine.
Fin de la première partie.
Nous publierons bientôt la deuxième partie de la traduction, en attendant nous attendons vos commentaires et vous invitons à , qui aura lieu aujourd'hui à 20h00.
Source : habr.com
