Read in English · Leer en español · Auf Deutsch lesen
Section 0.8 sur 0.8 · Débutant · 20 min de lecture
Exigences, gestion de versions, tests, livraison et parcours d’une requête
Leçon vidéo
5 min · narré en anglais, avec sous-titresÉcouter seulement (audio)
Lire la transcription
Construire un logiciel est un sport d’équipe qui suit une routine soignée. Les besoins sont consignés par écrit, chaque modification est enregistrée et vérifiée, et des tests automatiques servent de filet de sécurité. À la fin de cette leçon, nous suivrons un simple appui sur le bouton « Commander » à travers chaque partie d’un système de livraison de repas, pour rassembler tout le chapitre.
Un logiciel commence par un besoin. Certaines exigences disent ce qu’un système doit faire, par exemple : un client peut payer par carte. D’autres disent avec quel niveau de qualité, par exemple : le paiement se termine en moins de deux secondes. Beaucoup d’équipes écrivent les besoins sous forme de récits utilisateur. Par exemple : en tant que client affamé, je veux commander à nouveau un repas que j’ai déjà pris, afin de manger plus tôt. Des critères d’acceptation disent ensuite précisément quand le récit est terminé.
De nombreuses personnes modifient le même code chaque jour : les équipes utilisent donc la gestion de versions, presque toujours avec un outil appelé Git. Elle enregistre chaque modification, qui l’a faite et pourquoi. Chaque modification enregistrée est un commit, ici sur la ligne principale. Pour travailler sur quelque chose de nouveau, un développeur crée une branche : une ligne de travail séparée. Ici, deux commits ajoutent un bouton de pourboire et ses tests, sans déranger personne. Quand c’est prêt, le développeur ouvre une pull request. Des vérifications automatisées s’exécutent, et un collègue relit la modification. La revue détecte des erreurs, mais elle diffuse aussi les connaissances : au moins deux personnes comprennent chaque modification. Une fois approuvée, la branche est fusionnée dans main.
Toute modification risque de casser quelque chose qui fonctionnait. Les tests automatisés sont des programmes qui vérifient d’autres programmes, et ils se présentent en couches. À la base, on trouve les tests unitaires. Chacun vérifie un petit élément, comme une fonction, et s’exécute en quelques millisecondes : une équipe peut donc en avoir beaucoup. Au milieu, les tests d’intégration vérifient que des parties fonctionnent ensemble, comme le code des commandes avec une vraie base de données. Au sommet, quelques tests de bout en bout pilotent le système entier comme le ferait un utilisateur. Ils sont réalistes, mais lents et parfois instables. Le but est de détecter la plupart des problèmes avec des tests rapides et ciblés.
L’automatisation qui achemine une modification jusqu’aux clients s’appelle un pipeline. Avec l’intégration continue, chaque modification est fusionnée souvent, puis construite et testée automatiquement. Un échec revient directement au développeur, en quelques minutes. Vient ensuite le staging : une copie du système aussi proche que possible de la production, où l’on répète la mise en production. La production, c’est le système réel dont dépendent les vrais clients. Avec la livraison continue, une personne approuve chaque mise en production d’une simple pression sur un bouton. Avec le déploiement continu, chaque modification validée passe en production automatiquement.
Les équipes choisissent aussi comment organiser le travail. Dans une approche séquentielle, souvent appelée cycle en cascade, chaque phase se termine avant que la suivante commence. Elle convient aux exigences figées, mais les utilisateurs ne voient rien avant un stade tardif. Scrum, le cadre agile le plus utilisé, fonctionne par cycles courts appelés sprints, d’un mois ou moins, chacun se terminant par une revue. Kanban n’a pas de cycles fixes. Le travail circule sur un tableau visible, et l’équipe limite la quantité de travail en cours à un moment donné. Et le DevOps est une culture qui réunit la construction et l’exploitation du logiciel : vous le construisez, vous l’exploitez.
Maintenant, tout le chapitre en un seul instant. Un client appuie sur Commander dans une app de livraison de repas. L’app transforme le panier en JSON. D’abord, le DNS traduit le nom de l’entreprise en adresse IP. L’app envoie une requête HTTPS. Un équilibreur de charge, dans la région cloud de l’entreprise, la transmet à l’une des copies du service des commandes, qui tournent dans des conteneurs. Le service des commandes appelle l’API du prestataire de paiement, et attend. Le client ne doit pas voir « confirmée » avant que le paiement soit approuvé : cet appel est donc synchrone. Puis, en une seule transaction, la commande et ses articles sont enregistrés dans la base de données. Soit tout est enregistré, soit rien ne l’est. Enfin, un message OrderPlaced est déposé dans une file, et l’app affiche « confirmée ». Le service de notification le récupère quand il est prêt, et une notification push arrive sur le téléphone. Si ce service est brièvement indisponible, rien de visible ne casse.
Posez la question « et si ? » à chaque étape, et les questions d’architecture apparaissent. Et si l’appel de paiement expire ? Le débit a-t-il eu lieu ? Une clé unique envoyée avec la commande permet au service de redemander sans risque, sans débiter deux fois. Et si l’enregistrement de la commande échoue après que le paiement a réussi ? Le paiement et la base de données sont des systèmes distincts : la conception doit donc prévoir un moyen de rembourser ou de réessayer. Et si le trafic de l’heure du dîner triple ? On ajoute des copies du service des commandes, et la base de données devient le goulet d’étranglement probable. Aucune de ces questions ne porte sur l’écriture d’une fonction. Elles portent sur la façon dont les parties sont agencées.
Quelqu’un a dû décider de tout cela : ce qui est synchrone, où vivent les données, ce qui tourne où. Décider de l’agencement des parties, c’est l’architecture logicielle. Ainsi s’achève le chapitre zéro. Essayez le test facultatif du chapitre, puis passez au chapitre un : ce qu’est l’architecture logicielle.
Ce qu’il faut savoir
- Les exigences décrivent ce qu’un système doit faire et avec quel niveau de qualité ; les récits utilisateur (En tant que..., je veux..., afin de...) assortis de critères d’acceptation sont une manière légère et courante de saisir les besoins fonctionnels.
- Git enregistre chaque modification sous forme de commits ; les branches isolent le travail en cours, et les pull requests apportent une revue de code et des vérifications automatisées avant une fusion dans main.
- La pyramide des tests recommande beaucoup de tests unitaires rapides, moins de tests d’intégration et peu de tests de bout en bout, qui sont lents.
- Les modifications passent par des environnements de développement, de test et de staging avant la production ; plus le staging ressemble à la production, plus il détecte de problèmes.
- L’intégration continue vérifie automatiquement chaque modification ; la livraison continue garde le logiciel toujours prêt à être mis en production ; le déploiement continu met automatiquement en production chaque modification qui passe les vérifications.
- Le cycle en cascade, Scrum et Kanban organisent le travail différemment ; le DevOps est une culture de responsabilité partagée pour construire et exploiter les logiciels.
- Une simple requête dans un système réel traverse le DNS, HTTPS, un équilibreur de charge, des services, une transaction de base de données, des API tierces et des files d’attente ; décider de la façon dont ces parties sont agencées, c’est l’architecture logicielle.
D’une idée à une exigence
Un logiciel commence par un besoin : un restaurant veut prendre des commandes en ligne, un hôpital veut que les patients prennent eux-mêmes leurs rendez-vous. Transformer ce besoin en quelque chose qu’une équipe peut construire, c’est le travail des exigences. Certaines exigences décrivent ce que le système doit faire (« un client peut payer par carte ») ; d’autres décrivent avec quel niveau de qualité il doit le faire (« le paiement se termine en moins de deux secondes pour 95 % des clients »). Le chapitre 2 montre que la seconde catégorie, les attributs de qualité, guide la plupart des décisions d’architecture.
Beaucoup d’équipes saisissent les besoins fonctionnels sous forme de récits utilisateur (user stories) : de courtes descriptions écrites du point de vue de l’utilisateur. Kent Beck les a introduits dans l’Extreme Programming à la fin des années 1990, et une équipe de l’entreprise londonienne Connextra a conçu en 2001 le modèle que la plupart des gens utilisent aujourd’hui :
As a hungry customer,
I want to reorder a meal I have ordered before,
so that I can eat sooner without searching the menu again.
Acceptance criteria
- My last 10 orders appear on the home screen.
- Tapping "Reorder" fills the basket with the same items.
- Items that are no longer available are flagged, not silently dropped.Un récit est volontairement court et incomplet. Ron Jeffries le décrivait comme une carte, une conversation et une confirmation : la carte sert d’aide-mémoire, les détails se règlent en conversation entre les personnes qui veulent la fonctionnalité et celles qui la construisent, et les critères d’acceptation confirment quand elle est terminée. Les praticiens ne sont pas d’accord sur ce qu’il faut écrire à l’avance. Les équipes des secteurs réglementés, comme les dispositifs médicaux et l’aéronautique, doivent tenir des exigences formelles et traçables ; les équipes produit préfèrent souvent des récits plus légers, affinés juste avant le début du travail. Les deux approches sont légitimes dans leur contexte.
La gestion de versions avec Git
Le code source est le document partagé le plus précieux de l’équipe, et de nombreuses personnes le modifient chaque jour. La gestion de versions enregistre chaque modification, qui l’a faite et pourquoi, permet de travailler en parallèle sans écraser le travail des autres, et permet de restaurer n’importe quel état antérieur. Presque toutes les équipes utilisent aujourd’hui Git, créé par Linus Torvalds en 2005 pour le développement du noyau Linux, généralement avec un service d’hébergement comme GitHub, GitLab ou Bitbucket.
Quelques notions couvrent l’essentiel de l’usage quotidien. Un commit est un instantané enregistré d’un ensemble de modifications, accompagné d’un message qui l’explique (« Ajouter un bouton de pourboire au paiement »). Une branche est une ligne de travail séparée : un développeur crée une branche à partir de main, y fait des commits sans déranger personne et, une fois terminé, fusionne (merge) sa branche dans la ligne principale, ce qui combine les deux historiques. Si deux personnes ont modifié les mêmes lignes, Git signale un conflit de fusion qu’un humain doit résoudre.
Sur les services d’hébergement, la fusion passe généralement par une pull request (GitLab parle de merge request) : une page web qui présente la modification proposée, où des vérifications automatisées s’exécutent et où des collègues effectuent une revue de code, en lisant la modification, en posant des questions et en suggérant des améliorations avant de l’approuver. La revue détecte des défauts, mais ses bénéfices les plus importants sont la diffusion des connaissances (au moins deux personnes comprennent chaque modification) et la cohérence de la conception. Les architectes participent souvent à la revue des modifications qui touchent la structure ou les interfaces.
git switch -c feature/tip-button # create a branch and move onto it
# ... edit files ...
git add checkout.py test_checkout.py
git commit -m "Add tip button to checkout"
git push -u origin feature/tip-button # upload; then open a pull request
# after review and green checks, the branch is merged into mainLes équipes divergent sur la gestion des branches. Certaines gardent des branches de longue durée par fonctionnalité ou par version ; d’autres pratiquent le trunk-based development (développement basé sur le tronc), en fusionnant de petites modifications dans main au moins une fois par jour et en masquant les fonctionnalités inachevées derrière des interrupteurs appelés feature flags. Les recherches du programme DORA associent les branches de courte durée à de meilleures performances de livraison, mais le bon choix dépend aussi de la manière dont l’équipe met en production.
Les tests : la pyramide
Toute modification risque de casser quelque chose qui fonctionnait, ce qu’on appelle une régression. Les tests automatisés sont des programmes qui vérifient d’autres programmes : on peut donc les lancer à chaque modification en quelques minutes, au lieu de confier la vérification à des personnes pendant des jours. Ils se présentent en couches. Un test unitaire vérifie un petit élément, comme une fonction, de façon isolée, et s’exécute en quelques millisecondes. Un test d’intégration vérifie que des parties fonctionnent ensemble : le code des commandes avec une vraie base de données, ou la boutique avec l’environnement de test d’un prestataire de paiement. Un test de bout en bout pilote le système entier comme le ferait un utilisateur, par exemple en parcourant l’app de la carte jusqu’à la confirmation de commande.
La pyramide des tests de Mike Cohn, publiée dans son livre de 2009 Succeeding with Agile, suggère les proportions : beaucoup de tests unitaires, moins de tests d’intégration et peu de tests de bout en bout. Les couches supérieures sont plus réalistes, mais plus lentes, plus coûteuses à maintenir et plus sujettes aux échecs instables (flaky), qui apparaissent et disparaissent pour des raisons sans rapport avec la modification. Certains praticiens défendent une autre forme, par exemple davantage de tests d’intégration pour les systèmes qui servent surtout de liant entre des services ; le principe sur lequel tous s’accordent est de détecter la plupart des problèmes avec des tests rapides, fiables et ciblés.
def delivery_fee(basket_total, distance_km):
if basket_total >= 25:
return 0.0 # free delivery on larger orders
return round(1.50 + 0.40 * distance_km, 2)
def test_free_delivery_over_threshold():
assert delivery_fee(30.00, 5) == 0.0
def test_fee_grows_with_distance():
assert delivery_fee(10.00, 5) == 3.50Les environnements : du développement à la production
Le code traverse plusieurs environnements sur le chemin qui le mène aux clients, chacun étant une copie séparée du système avec ses propres serveurs, données et réglages. Le but est de trouver les problèmes là où ils sont peu coûteux et sans danger, avant qu’ils n’atteignent la production, l’environnement réel dont dépendent les vrais utilisateurs.
| Environnement | Qui l’utilise | Données | Objectif |
|---|---|---|---|
| Développement | Un développeur, sur un ordinateur portable ou un espace cloud personnel | Réduites, fictives | Écrire et essayer du code rapidement. |
| Test (ou intégration) | L’équipe et le pipeline automatisé | Fictives ou anonymisées | Lancer des tests automatisés et exploratoires sur les modifications combinées. |
| Staging (ou préproduction) | Testeurs, product owners, parfois des clients sélectionnés | Semblables à la production en forme et en volume, jamais de données personnelles brutes sans garanties | Répéter la mise en production sur une copie aussi proche que possible de la production. |
| Production | Vrais clients | Réelles | Faire tourner l’activité. Les modifications n’arrivent que par le pipeline. |
Plus les environnements diffèrent de la production, plus les problèmes passent entre les mailles : une base de test de cent lignes ne révélera pas l’index manquant qui fait durer une requête quarante secondes face à dix millions de lignes. Il est plus facile de garder des environnements semblables quand ils sont construits à partir des mêmes images de conteneur et de la même configuration scriptée, un thème de l’infrastructure en tant que code.
Intégration, livraison et déploiement continus
L’intégration continue (CI) est la pratique qui consiste à fusionner fréquemment, au moins une fois par jour, le travail de chacun dans la ligne principale partagée, un build et des tests automatisés vérifiant chaque modification. Elle est née de l’Extreme Programming dans les années 1990. Son intérêt est que les problèmes d’intégration sont détectés en quelques minutes, tant que la modification est fraîche dans l’esprit de son auteur, au lieu de l’être lors d’une pénible « phase d’intégration » des semaines plus tard. Une équipe qui pratique la CI traite un build en échec comme une urgence : le réparer passe avant tout nouveau travail.
La livraison continue (CD) prolonge la CI pour que le logiciel soit toujours prêt à être mis en production : chaque modification qui passe le pipeline pourrait être mise en production d’une simple pression sur un bouton, et la mise en production devient une décision métier de routine plutôt qu’un événement risqué. L’approche a été exposée par Jez Humble et David Farley dans leur livre de 2010 Continuous Delivery. Le déploiement continu va un cran plus loin et met automatiquement en production chaque modification qui passe le pipeline, sans approbation humaine ; les équipes qui le pratiquent peuvent déployer de nombreuses fois par jour.
L’automatisation qui achemine une modification du commit jusqu’à la production est un pipeline. Comme chaque étape est automatisée et identique à chaque fois, les mises en production cessent de dépendre d’une personne qui doit se souvenir d’une liste de contrôle à minuit.
Liste de contrôle : avant qu’une modification n’atteigne la production
Ce que le processus d’une équipe mature vérifie, le plus souvent automatiquement, pour chaque modification.
- La modification est liée à un récit ou à un ticketN’importe qui pourra retrouver plus tard pourquoi elle a été faite.
- Elle est petiteLes petites modifications sont plus faciles à relire, à tester, à déployer et, si nécessaire, à annuler.
- Un collègue l’a reluePar une pull request, avec des questions qui ont obtenu réponse et des commentaires résolus.
- Les tests automatisés passent à tous les niveauxTests unitaires et d’intégration dans la CI, et les vérifications de bout en bout qui couvrent le parcours concerné.
- Elle a tourné en stagingLe même build, le même mécanisme de configuration et les mêmes étapes de déploiement qu’en production.
- Il existe un chemin de retourUn retour arrière (rollback) ou un feature flag peut la désactiver rapidement en cas de problème.
- Quelqu’un remarquera si elle casse quelque choseLa supervision (monitoring) et les alertes couvrent ce que la modification touche (chapitre 9, observabilité).
Façons de travailler : cycle en cascade, Scrum et Kanban
Les équipes choisissent aussi comment organiser le travail lui-même. Dans une approche séquentielle, souvent appelée cycle en cascade (waterfall), le projet traverse des phases dans l’ordre : exigences, conception, implémentation, tests, déploiement. Chaque phase se termine avant que la suivante commence. Le nom est généralement attribué à l’article de Winston Royce de 1970, bien que Royce n’ait pas employé ce mot et qu’il ait en fait averti qu’un passage unique à travers les phases était risqué. Les plans séquentiels conviennent encore aux travaux dont les exigences sont figées et où le changement coûte très cher, comme certains projets réglementés ou dépendants du matériel. Leur faiblesse, pour la plupart des logiciels, est que les utilisateurs ne voient rien avant un stade tardif : les malentendus apparaissent donc quand ils coûtent le plus cher à corriger.
Les approches agiles, nommées dans le Manifeste agile de 2001, livrent un logiciel qui fonctionne par cycles courts et ajustent les plans à mesure qu’elles apprennent. Scrum est le cadre le plus utilisé : une petite équipe travaille par cycles fixes appelés sprints, d’un mois ou moins, chacun commençant par une planification et se terminant par une revue du travail et une rétrospective sur la façon dont l’équipe a travaillé. Le Guide Scrum de 2020 définit trois responsabilités : le Product Owner (qui décide de ce qui a le plus de valeur), le Scrum Master (qui aide l’équipe à utiliser Scrum efficacement) et les Developers (qui font le travail). Kanban, adapté au logiciel à partir du système de production de Toyota, n’a pas de cycles fixes : les éléments de travail circulent sur un tableau visible (à faire, en cours, en revue, terminé), et l’équipe limite le nombre d’éléments en cours à un moment donné, afin que le travail soit terminé avant d’en commencer davantage.
Aucune de ces approches ne convient à toutes les équipes, et beaucoup d’organisations les combinent : Scrum pour les équipes produit, Kanban pour le support et l’exploitation, un plan plus séquentiel autour d’une échéance réglementaire fixe. Qualifier un processus d’« agile » ne le rend pas agile ; ce qui compte, c’est qu’un logiciel qui fonctionne parvienne à de vrais utilisateurs assez souvent pour apprendre d’eux.
DevOps : une seule équipe responsable, du code jusqu’au client
Traditionnellement, les développeurs écrivaient le logiciel et une équipe d’exploitation distincte le faisait tourner, avec des incitations contradictoires : les développeurs étaient récompensés pour le changement, l’exploitation pour la stabilité. Le DevOps est le mouvement, baptisé lors de la première conférence DevOpsDays à Gand en 2009, qui réunit les deux. C’est avant tout une culture de responsabilité partagée (« you build it, you run it » : vous le construisez, vous l’exploitez), soutenue par des pratiques comme le CI/CD, l’infrastructure en tant que code, la supervision et les revues d’incidents sans recherche de coupable. Ce n’est ni un intitulé de poste ni un outil, même si l’on vend les deux sous ce nom. Le programme de recherche DORA est surtout connu pour mesurer la performance de livraison avec quatre indicateurs clés : la fréquence de déploiement d’une équipe, le temps qu’une modification met à atteindre la production, la fréquence des échecs des modifications et la rapidité du rétablissement du service après une défaillance.
Exemple commenté : le parcours d’un simple appui
Tout ce chapitre se rejoint en un seul instant. Un client a rempli un panier dans une app de livraison de repas et appuie sur Commander. En une seconde ou deux, l’écran affiche « Commande confirmée », et vingt minutes plus tard le téléphone vibre : « Votre livreur est en route ». Voici ce qui se passe, étape par étape, avec la notion derrière chaque étape et l’endroit où elle a été présentée.
Pas à pas
- 0. L’app construit la requêteL’app est un logiciel installé sur le téléphone (section 0.1). Elle rassemble le panier à partir de ses structures de données en mémoire (section 0.2) et les transforme en corps JSON : restaurant, articles, adresse de livraison et une clé de commande unique générée sur le téléphone.
- 1. DNSL’app a besoin de l’adresse de
api.fooddelivery.example. Le téléphone interroge un résolveur DNS, qui renvoie une adresse IP, souvent depuis un cache (section 0.4). - 2. HTTPSL’app ouvre une connexion TCP et une session TLS, en vérifiant le certificat du serveur, puis envoie
POST /v1/ordersavec un jeton d’accès qui prouve quel client est connecté (sections 0.4 et 0.6). - 3. Équilibreur de chargeLa requête atteint un équilibreur de charge dans la région cloud de l’entreprise. Il déchiffre le HTTPS et transmet la requête à l’une des copies saines du service des commandes, qui tournent dans des conteneurs répartis sur plusieurs zones de disponibilité (section 0.7).
- 4. API et paiementOn accède au service des commandes par son API REST. Son code, organisé en modules (section 0.3), valide le panier, puis appelle l’API web du prestataire de paiement pour autoriser la carte, en attendant la réponse de façon synchrone avec un délai d’expiration (timeout), car le client ne doit pas lire « confirmée » tant que le paiement n’est pas approuvé (section 0.6). Il envoie la clé de commande comme clé d’idempotence, pour que, si l’appel fait l’objet d’une nouvelle tentative, la carte ne soit débitée qu’une seule fois.
- 5. Transaction de base de donnéesDans une seule transaction ACID, le service insère la commande et ses articles et enregistre la référence du paiement. Soit tout est enregistré, soit rien ne l’est ; une fois validée, la transaction survit à une panne (section 0.5). Un index sur l’identifiant du client rendra son historique de commandes rapide à charger.
- 6. File d’attenteLe service dépose un message
OrderPlaceddans une file de messages et répond immédiatement201 Created. L’app affiche « Commande confirmée ». Tout le reste se déroule de façon asynchrone (section 0.6). - 7. Les autres services réagissentLe service de la tablette du restaurant, le service d’affectation des livreurs et le service de notification lisent chacun le message quand ils sont prêts. Si l’un d’eux est brièvement indisponible, ses messages attendent dans la file.
- 8. Notification pushLe service de notification réagit à
OrderPlaced, puis plus tard à un message similaire quand un livreur est affecté, en appelant le service push géré par Apple ou Google, une autre API tierce, qui remet la notification sur le téléphone du client. - 9. Et derrière tout celaChaque morceau de code sur ce chemin a été écrit à partir d’un récit utilisateur, relu dans une pull request, testé à plusieurs niveaux et mis en production par un pipeline CI/CD, en passant par le staging (cette section).
Exemple commenté
Exemple commenté : ce que nous apprend le parcours
Posez la question « et si ? » à chaque étape, et les questions d’architecture apparaissent.
| Et si l’appel de paiement expire ? | Le débit a-t-il eu lieu ou non ? La clé d’idempotence permet au service des commandes de redemander sans risque, sans débiter deux fois. |
|---|---|
| Et si l’enregistrement en base de données échoue après le paiement ? | Le paiement et la base de données sont des systèmes distincts : aucune transaction ACID unique ne couvre les deux. La conception doit prévoir un moyen de rembourser ou de réessayer, un problème que le chapitre 6 résout avec les sagas. |
| Et si le service de notification est en panne ? | Rien de visible ne casse : les commandes sont toujours prises et les messages attendent dans la file. C’est la raison pour laquelle cette étape est asynchrone. |
| Et si le trafic de l’heure du dîner triple ? | L’équilibreur de charge répartit les requêtes sur davantage de copies du service des commandes, ajoutées par l’autoscaling ; la base de données devient alors le goulet d’étranglement probable. |
| Et si une mise en production casse l’étape de paiement ? | Les tests du pipeline devraient le détecter ; sinon, la supervision déclenche une alerte et l’équipe revient à la version précédente. |
Aucune de ces questions ne porte sur la manière d’écrire une fonction. Elles portent sur la façon dont les parties sont agencées et sur ce que chaque partie promet aux autres.
Pourquoi c’est important pour l’architecture
Le parcours d’un simple appui mobilise une douzaine de composants, trois organisations et des communications à la fois synchrones et asynchrones, et il a bien fallu le concevoir : quelqu’un a décidé que le paiement est synchrone et que les notifications ne le sont pas, que les commandes résident dans une base de données relationnelle, que le service tourne dans des conteneurs sur deux zones, que le prestataire de paiement est isolé derrière un seul module. Décider de l’agencement de ces parties, des qualités qu’atteint chaque agencement et de ce qu’il coûte, et consigner pourquoi, c’est l’architecture logicielle. La manière dont le logiciel est construit compte aussi pour l’architecture : une architecture qu’on ne peut pas tester par morceaux, ni mettre en production sans coordonner dix équipes, ralentit chaque modification. Le chapitre 1 commence par ce qu’est l’architecture logicielle.
Vérifiez votre compréhension
Quelle est la différence entre livraison continue et déploiement continu ?
Avec la livraison continue, chaque modification validée peut être mise en production d’une simple pression sur un bouton, mais c’est une personne qui décide quand. Avec le déploiement continu, chaque modification validée est mise en production automatiquement.
Pourquoi la pyramide des tests place-t-elle les tests unitaires à la base ?
Ils sont rapides, peu coûteux et fiables : une équipe peut donc en lancer des milliers à chaque modification et obtenir un retour en quelques minutes. Les tests de bout en bout, plus lents et plus fragiles, sont réservés aux quelques parcours qui en ont besoin.
Dans le parcours d’un simple appui, pourquoi l’appel de paiement est-il synchrone, mais la notification asynchrone ?
L’app ne doit pas afficher « confirmée » tant que le paiement n’est pas approuvé : elle attend donc cette réponse. La notification peut être envoyée un peu plus tard : elle passe donc par une file, et sa défaillance ne peut pas bloquer la prise de commande.
Quels sont les deux principaux avantages d’une pull request, au-delà de la détection des bugs ?
Elle diffuse les connaissances, car au moins une autre personne comprend chaque modification, et elle maintient la cohérence de la conception du code, car les relecteurs peuvent remettre en question les choix structurels.
Sources et lectures complémentaires
Une question sur cette section ? ArchitectBot, l’assistant d’étude IA du cours, répond d’abord à partir du cours.
Demander : « En quoi la manière dont mon équipe teste et déploie le code influe-t-elle sur l’architecture que nous devrions choisir ? »