Réponds à voix haute ou par écrit avant d’ouvrir la réponse : c’est l’effort de rappel qui fait retenir. Marque ensuite la question « Je savais » ou « À revoir », puis filtre sur « À revoir » pour la prochaine séance. Les marques restent dans ce navigateur.
Rappel actif
Restitue de mémoire, sans support.
Sans regarder le cours : un style architectural répond à cinq questions fondamentales. Cite-les toutes, avec un exemple concret de réponse pour chacune.
Question Exemple concret Comment décomposer le système ? En couches, en services, en modules Comment les composants communiquent ? Appels directs, messages, événements Comment sont gérées les données ? Base centralisée, base par service Comment garantir la scalabilité ? Duplication horizontale, partitionnement Comment assurer la maintenabilité ? Séparation des responsabilités, couplage faible Astuce mémoire : décomposer, communiquer, données, scalabilité, maintenabilité. Ce sont exactement les lignes du tableau comparatif des quatre styles.
Reconstitue la chaîne qui va de l’entreprise au framework : les six étapes dans l’ordre, et la question à laquelle chacune répond.
- Entreprise : que fait l’organisation ? (ses métiers, ses objectifs)
- SI : comment l’entreprise gère et échange ses informations ?
- Architecture : comment organiser les différentes parties du système ?
- Style : quelle philosophie d’organisation adopter ?
- Patron : quelle solution réutilisable appliquer à un problème précis ?
- Framework : avec quels outils implémenter cette solution ?
Le point à retenir est l’ordre : le framework arrive en dernier. On ne choisit pas Spring puis une architecture, c’est l’inverse.
Cite les cinq fonctions de l’ESB, puis dis laquelle fait de lui un « chef d’orchestre » plutôt qu’un simple tuyau.
Routage des messages, transformation de données (XML vers JSON), orchestration, sécurité et gouvernance, gestion des protocoles (SOAP, FTP, HTTP).
C’est l’orchestration : l’ESB coordonne l’enchaînement de plusieurs services pour réaliser un processus métier complexe. Le routage seul ne ferait qu’acheminer.
Distingue
Deux notions proches : dis ce qui les sépare vraiment.
SOA et microservices découpent tous deux le système en services. Donne trois différences concrètes qui ne se résument pas au nombre ou à la taille des services.
Critère SOA Microservices Découpage Services métier partagés et réutilisables par plusieurs applications Contextes métier autonomes Base de données Partagée ou dédiée Une par service Communication Via un intermédiaire central (ESB), SOAP / WSDL REST ou message broker, directement entre services Déploiement Services via ESB / UDDI 1 service = 1 déploiement indépendant L’idée clé : SOA vise la réutilisation et met l’intelligence dans le bus ; les microservices visent l’autonomie et chaque service possède ses données.
L’ESB et l’API Gateway sont tous deux des « intermédiaires ». Qu’est-ce qui les sépare (où ils se placent, ce qu’ils font) ?
- L’ESB (SOA) se place entre les services : il route, transforme les formats, fait le pont entre protocoles et surtout orchestre un processus métier qui enchaîne plusieurs services.
- L’API Gateway (microservices) se place entre le client et les services : point d’entrée unique, il route chaque requête du frontend vers le bon microservice et centralise authentification, load balancing et limitation de débit.
La Gateway ne porte pas de processus métier ; l’ESB, si.
Architecture en couches (Layered) et architecture N-Tiers : les deux empilent des niveaux qui ne parlent qu’au voisin. Où est la vraie différence ? Une application Spring Boot avec Controller, Service et Repository a combien de couches et combien de tiers ?
Les couches sont de l’architecture logique (comment le code est organisé, diagramme de packages). Les tiers sont de l’architecture physique (où le code tourne, sur quelles machines et quels ports, diagramme de déploiement).
L’application Spring Boot a 3 couches (présentation, service, persistance) mais elles tournent toutes dans un seul tier : le backend Tomcat sur le port 8080. Dans l’exemple N=4, les autres tiers sont le client, le frontend (Nginx :4200) et MySQL (:3306).
Bibliothèque ou framework : le critère n’est pas la taille de l’outil. Quel est-il ? Illustre-le avec ce qui se passe quand une requête HTTP arrive sur un
@RestController.Le critère est qui contrôle le déroulement de l’exécution. Avec une bibliothèque, c’est ton code qui l’appelle quand il en a besoin. Avec un framework, c’est le framework qui appelle ton code au moment où il le juge nécessaire : c’est l’inversion de contrôle (IoC), le principe Hollywood « Don’t call us, we’ll call you ».
Tu n’écris jamais l’appel à ta méthode de contrôleur : Spring reçoit la requête et appelle ta méthode. Tu remplis un point d’extension qu’il a défini.
En CQRS, pourquoi le modèle d’écriture reste-t-il normalisé alors que le modèle de lecture est dénormalisé ? Qui applique les règles métier, et de quel côté ?
Les deux flux n’ont pas le même besoin :
- Écriture : le Command handler valide et applique la règle métier. Le modèle doit être strict et normalisé, il est le garant de la cohérence.
- Lecture : le Query handler n’applique aucune règle métier, il lit une vue dénormalisée, optimisée pour l’affichage (moins de jointures, plus rapide).
Séparer les deux permet d’optimiser chaque flux séparément au lieu d’un compromis qui ne sert bien aucun des deux.
Explique pourquoi
Le mécanisme derrière la règle.
Le cours dit qu’une mauvaise architecture « ne se voit pas immédiatement ». Pourquoi ? Appuie-toi sur les avantages et inconvénients du monolithe.
Les avantages du monolithe se voient au début : simple à développer, à déployer, à déboguer en local, un seul projet. Ses inconvénients n’apparaissent qu’avec la croissance : code difficile à maintenir, redéploiement complet pour une petite modification, équipes qui se marchent dessus, impossible de scaler un seul module.
Le coût arrive donc plus tard, sous forme de dette technique. D’où l’objectif d’anticiper dès la conception.
Pourquoi chaque microservice a-t-il sa propre base de données ? Que perdrait-on avec une base partagée, et quel prix paie-t-on pour cette séparation ?
Une base partagée couple les services par leur schéma : modifier une table pour un service peut casser les autres, et on ne peut plus les déployer indépendamment. On perdrait aussi la technologie libre par service (dans l’exemple, Restaurants est sur MongoDB, Paiement sur PostgreSQL).
Le prix : multiplication des bases à gérer et transactions distribuées complexes, puisqu’une opération qui touche deux services ne tient plus dans une seule transaction.
Pourquoi le patron hexagonal fait-il définir les ports par le domaine et non par la technologie (JPA, REST) ? Que se passerait-il dans le cas inverse ?
Le domaine ne doit dépendre d’aucune technologie. S’il définit lui-même l’interface dont il a besoin (port sortant « sauvegarder ») ou ce qu’il propose (port entrant « réserver un véhicule »), ce sont les adaptateurs qui dépendent du domaine, pas l’inverse.
Si l’interface venait de JPA, le domaine importerait JPA : passer de MySQL à MongoDB obligerait à modifier le domaine, ce que le patron veut justement éviter.
En quoi la règle « chaque couche ne dépend que de la couche immédiatement inférieure » permet-elle de tester la couche Service sans base de données réelle ?
Le Service ne connaît que la couche persistance, à travers ce qu’elle expose (le repository). On peut donc remplacer cette couche par une fausse implémentation pendant le test, sans que le Service s’en aperçoive.
Si le contrôleur ou le service parlaient directement à la base, cette substitution serait impossible : la règle isole les changements et rend chaque couche testable seule.
Pourquoi le cycle en V est-il courant dans l’aéronautique et l’embarqué critique, alors que ce module suit un modèle agile ?
Le cycle en V associe chaque phase de conception à une phase de test miroir : chaque exigence est tracée jusqu’à son test. C’est ce qu’exige un système critique, avec des besoins stables et une forte exigence de preuve.
Le choix dépend du niveau d’incertitude et du besoin de livraisons rapprochées : le module avance séance après séance par incréments, d’où l’agile.
Cas pratique
Choisis et justifie avec les critères du cours.
Trois développeurs lancent le MVP d’une application de réservation, à livrer en deux mois. Quel style choisis-tu ? Justifie avec deux critères du tableau comparatif, puis cite deux signaux qui te feraient reconsidérer ce choix plus tard.
Monolithique. Complexité initiale faible, cas d’usage « petit projet », un seul projet et un seul déploiement : idéal pour une petite équipe et un délai court. Les microservices (complexité très élevée, Docker, Kubernetes, monitoring distribué) coûteraient plus qu’ils ne rapportent.
Signaux de remise en cause : un module qui doit tenir une charge bien plus forte que les autres (on ne peut scaler que le tout), les déploiements qui deviennent risqués parce qu’une petite modification redéploie tout, une équipe qui grandit et se marche dessus sur le même projet.
Une banque possède des applications Java, .NET et un vieux système qui n’échange que par FTP. Elles doivent collaborer dans un processus « ouverture de compte » qui enchaîne quatre applications. Quel style, et quelles fonctions précises de la pièce centrale vont servir ?
SOA avec un ESB (cas d’usage : SI hétérogènes).
- Gestion des protocoles : faire le pont entre FTP, SOAP, HTTP.
- Transformation de données : convertir les formats entre applications hétérogènes.
- Orchestration : enchaîner les quatre applications pour le processus « ouverture de compte ».
- Interopérabilité (pilier SOA) : Java et .NET communiquent grâce à des standards ouverts.
Un tableau de bord de ventes est consulté des milliers de fois par minute, mais les données ne changent que quelques fois par heure, et chaque écriture doit respecter des règles métier strictes. Quel patron, et quelle conséquence l’utilisateur peut-il observer juste après une mise à jour ?
CQRS : modèle d’écriture normalisé et strict pour les règles métier, modèle de lecture dénormalisé (vue ou cache) pour absorber les lectures.
Conséquence : si les deux modèles sont synchronisés de façon asynchrone, on a une cohérence à terme. Juste après une écriture, le tableau de bord peut encore afficher l’ancienne valeur pendant un court instant.
Dans AutoLoc, on veut stocker les véhicules dans MongoDB au lieu de MySQL, sans toucher au calcul du tarif de location. Avec le patron hexagonal, qu’est-ce qui change exactement, et qu’est-ce qui ne bouge pas ?
- Change : l’adaptateur. On remplace le repository JPA (MySQL) par un adaptateur MongoDB qui implémente le même port.
- Ne bouge pas : le port sortant (l’interface « sauvegarder un véhicule », définie par le domaine) et tout le domaine, donc le calcul du tarif.
C’est la promesse du patron : remplacer un adaptateur sans modifier une seule ligne du domaine.
Dans l’application de livraison, on ajoute un service « Fidélité » qui donne des points à chaque commande. Compare le travail nécessaire avec des appels directs et avec une architecture Event-Driven.
- Appels directs : il faut modifier
CommandeServicepour qu’il appelle aussiFideliteService, comme il appelle déjà Notification, Livreur et Stock. Chaque nouveau service impose de toucher au producteur : couplage fort. - Event-Driven :
CommandeServicepublie déjàCommandePassée. Le nouveau service s’abonne à cet événement. Aucune ligne deCommandeServicene change, puisque le producteur ne connaît pas ses consommateurs.
- Appels directs : il faut modifier
Vendredi soir, le service Paiement de l’application de livraison est saturé, les autres fonctionnent normalement. Décris la réaction possible si l’application est un monolithe, puis si elle est en microservices.
- Monolithe : scalabilité globale uniquement. Il faut dupliquer tout le backend (le JAR entier) pour soulager le seul paiement, et la saturation peut dégrader toute l’application.
- Microservices : scalabilité fine, on ajoute des instances du seul service Paiement (port 8084). Les autres services ne sont pas touchés, et la panne ou la lenteur reste contenue (résilience).
Trouve l'erreur
Chaque affirmation contient au moins une faute.
« Notre application est en microservices : trois modules Maven (commande, livreur, paiement) compilés ensemble dans un seul JAR, qui partagent la même base MySQL. »
C’est un monolithe (éventuellement bien modularisé). Les deux marqueurs du monolithe sont là : un unique JAR, donc un seul déploiement, et une base unique au schéma commun.
Pour parler de microservices, il faudrait que chaque service soit un projet à part entière, déployé indépendamment, avec sa propre base.
« Dans notre MVC, le Contrôleur calcule le prix TTC de la commande et applique la remise fidélité, puis transmet le résultat à la Vue. »
Le calcul du prix et la remise sont de la logique métier : elle appartient au Modèle. Le Contrôleur reçoit l’action, met à jour le modèle et choisit la vue, sans porter les règles.
Laisser le métier glisser dans le contrôleur mène au « Fat Controller », la limite connue de MVC.
« Notre architecture suit CQRS : la Query qui affiche un produit incrémente aussi son compteur de vues. »
Une Query ne modifie jamais l’état du système, aucun effet de bord. Incrémenter un compteur est une écriture : elle doit passer par une Command (traitée par le Command handler), séparée de la lecture.
« Dans notre architecture microservices, Eureka reçoit toutes les requêtes du frontend et les redirige vers le bon service. »
C’est le rôle de l’API Gateway (point d’entrée unique, routage, authentification, load balancing). Eureka est le Service Registry : l’annuaire où les microservices s’enregistrent pour être découverts (Service Discovery). La Gateway peut s’en servir pour trouver les services, mais ce n’est pas Eureka qui reçoit les requêtes du client.
« Pour documenter l’architecture physique, j’ai fait un diagramme de déploiement qui montre que
ReservationControllerdépend deReservationService, qui dépend deReservationRepository. »Des dépendances entre classes ou packages, c’est de l’architecture logique (comment le code est structuré) : on la décrit avec un diagramme de packages.
Un diagramme de déploiement montre où tourne le code : les nœuds (Nginx :4200, Tomcat :8080, MySQL :3306) et les protocoles entre eux (HTTPS/REST, JDBC/TCP-IP).
« Avec SOA, le service Facturation appelle directement le service Clients en connaissant sa structure interne, ce qui est plus rapide. »
Cela viole deux piliers SOA : le faible couplage (les services ne dépendent pas directement les uns des autres, ils passent par des contrats et par l’ESB) et l’abstraction / encapsulation (le consommateur ignore l’implémentation, seule l’interface compte).
Lis le code
Relie le code aux concepts.
Quelle règle de l’architecture en couches ce code viole-t-il, de deux façons ? Comment le corriger ?
@RestController public class ReservationController { @Autowired private ReservationRepository repository; @PostMapping("/reservations") public Reservation creer(@RequestBody Reservation r) { if (r.getDateFin().isBefore(r.getDateDebut())) { throw new IllegalArgumentException("Dates invalides"); } return repository.save(r); } }- La couche présentation saute la couche service et parle directement au
@Repository: elle ne dépend plus de la couche immédiatement inférieure. - Une règle métier (vérification des dates) vit dans le contrôleur, alors qu’elle appartient à la couche métier.
Correction : créer un
ReservationServiceannoté@Servicequi porte la règle et appelle le repository ; le contrôleur n’appelle plus que le service. La règle devient testable sans HTTP ni base réelle.- La couche présentation saute la couche service et parle directement au
Dans ce code, repère le domaine, le port (entrant ou sortant ?) et l’adaptateur. Que faut-il écrire pour passer à MongoDB ?
public interface VehiculeStockage { void sauvegarder(Vehicule v); Vehicule trouver(Long id); } public class LocationService { private final VehiculeStockage stockage; public double tarif(Long vehiculeId, int jours) { ... } } @Repository public class JpaVehiculeStockage implements VehiculeStockage { ... }- Domaine :
LocationService(etVehicule), qui ne connaît aucune technologie. - Port sortant :
VehiculeStockage, une interface qui exprime ce dont le domaine a besoin. - Adaptateur :
JpaVehiculeStockage, qui implémente le port avec JPA.
Pour MongoDB : écrire une nouvelle classe, par exemple
MongoVehiculeStockage implements VehiculeStockage, et la brancher à la place.LocationServiceetVehiculeStockagene changent pas.- Domaine :
Ces trois annotations correspondent à quelles couches, et à quels modules Spring ? Dans quel ordre une requête les traverse-t-elle, aller et retour ?
@Service,@RestController,@RepositoryAnnotation Couche Module Spring @RestControllerPrésentation Spring MVC @ServiceService (métier) Spring Framework @RepositoryPersistance Spring Data Aller :
@RestController→@Service→@Repository→ base de données. La réponse fait le chemin inverse.
Vrai ou faux, justifie
La justification compte plus que le verdict.
« En passant d’un monolithe à une architecture N-Tiers, on règle le problème de scalabilité. »
Faux. En N-Tiers, l’ensemble du backend reste déployé en un seul bloc : une montée en charge oblige à scaler toute l’application, pas un tier spécifique. La séparation des tiers améliore la maintenance et le travail en équipe, pas la scalabilité fine (celle-là, ce sont les microservices).
« Le système d’information d’une entreprise, c’est l’ensemble de ses logiciels et serveurs. »
Faux. Le SI est un ensemble organisé de ressources : personnes, matériel, logiciels, données et procédures. Logiciels et serveurs forment le système informatique, qui n’est que le support technique du SI.
« Choisir Spring Boot est la première décision d’architecture d’un projet. »
Faux. Le framework arrive en dernier : on choisit d’abord le style puis les patrons, et le framework est l’outil qui les implémente. « Spring n’est qu’un outil : il prend tout son sens une fois les concepts d’architecture compris. »
« Event-Driven est un patron de communication, au même titre que Publish/Subscribe. »
Faux. Event-Driven est un style architectural (l’organisation globale du système, l’un des quatre styles). Publish/Subscribe est le patron de communication qui le met en œuvre : un émetteur publie sans connaître ses destinataires, qui s’abonnent au sujet. Même idée, deux niveaux : plan d’urbanisme contre plan d’un bâtiment.
« Avec MVC, on peut ajouter une application mobile à côté du site web sans toucher au Modèle. »
Vrai. Le Modèle ne connaît ni la Vue ni le Contrôleur, et un même Modèle peut être observé par plusieurs Vues (pattern Observer). Une Vue peut être remplacée ou ajoutée (web, mobile, API) sans toucher au Modèle.
« En microservices, une panne d’un service ne peut jamais affecter les autres. »
Faux, dans sa forme absolue. Le cours dit qu’une panne n’impacte pas tout le système (résilience), pas qu’elle n’a aucun effet : un service qui en appelle un autre en HTTP/REST synchrone subit sa panne ou sa latence. C’est aussi pourquoi la communication réseau et le debug distribué figurent dans les inconvénients.
Classe
Range chaque élément et explique les cas limites.
Range chaque élément du côté logique ou physique :
@Service, Tomcat :8080, diagramme de packages, MySQL :3306, couche persistance, Nginx :4200, JDBC/TCP-IP, diagramme de déploiement.- Logique (comment le code est structuré) :
@Service, couche persistance, diagramme de packages. - Physique (où tourne le code) : Tomcat :8080, MySQL :3306, Nginx :4200, JDBC/TCP-IP, diagramme de déploiement.
- Logique (comment le code est structuré) :
Range ces six patrons dans leur famille (structurel, communication, traitement), en donnant pour chaque famille la question à laquelle elle répond : Hexagonal, Publish/Subscribe, CQRS, API Gateway, Couches, MVC.
Famille Question Patrons Structurels Comment organiser les composants ? Couches, Hexagonal Communication Comment les faire communiquer ? Publish/Subscribe, API Gateway Traitement Comment organiser la logique applicative à l’intérieur d’un composant ? MVC, CQRS Style ou patron ? Microservices, MVC, SOA, CQRS, Event-Driven, Hexagonal, Monolithique, API Gateway. Pour les cas qui prêtent à confusion, explique.
- Styles : Monolithique, SOA, Microservices, Event-Driven.
- Patrons : MVC, CQRS, Hexagonal, API Gateway.
Pièges : l’API Gateway apparaît dans le style microservices, mais c’est un patron de communication qu’on y applique. Event-Driven est un style, alors que son cousin Publish/Subscribe est un patron.
Associe chaque framework à sa description : Spring, Jakarta EE, Quarkus, Micronaut. (a) spécifications standardisées, plusieurs implémentations ; (b) créé par Red Hat, compilation native GraalVM ; (c) alternative légère à J2EE / EJB, créé en 2003 ; (d) JVM, supporte Java, Groovy et Kotlin.
- (a) Jakarta EE : ex Java EE, transféré à Eclipse en 2017, implémenté par WildFly, Payara, GlassFish.
- (b) Quarkus : 2019, démarrage en millisecondes, pensé pour Kubernetes et le serverless.
- (c) Spring : Rod Johnson, écosystème Boot, Cloud, Security…
- (d) Micronaut : proche de Spring Boot et Quarkus (injection de dépendances, AOP, auto-configuration).
Et si...
Prévois la conséquence.
Et si un bug provoque une fuite mémoire dans le module Livreurs ? Compare l’impact dans un monolithe et en microservices.
- Monolithe : tous les modules partagent le même processus (un seul JAR). La fuite finit par faire tomber tout le backend : commandes, paiement, restaurants compris.
- Microservices : seul le service Livreurs (port 8082) tombe. Les autres continuent, même si les fonctions qui dépendent des livreurs sont dégradées.
Et si, dans une architecture Event-Driven, le service d’envoi d’email est en panne au moment où
CommandePasséeest publié ? Que deviennent la commande et les autres consommateurs ?La commande est validée quand même :
CommandeServicea publié l’événement sans attendre personne. Les autres consommateurs (restaurant notifié, livreur cherché, stock mis à jour) réagissent indépendamment et en parallèle, la panne de l’email ne les bloque pas.Avec des appels directs,
CommandeServiceaurait dû gérer l’échec de l’appel à NotificationService lui-même.Et si on ajoute un tier de plus entre le frontend et le backend (par exemple un proxy) dans l’architecture N-Tiers ? Quel avantage espère-t-on, et quel inconvénient le cours annonce-t-il ?
On gagne en séparation des responsabilités : le nouveau tier peut évoluer, être remplacé ou testé indépendamment. Mais le cours prévient que la multiplication des tiers peut introduire une latence supplémentaire, puisque chaque requête traverse un saut réseau de plus.