Aller au contenu

Concepts : un parcours de lecture

Résumé. Ces pages expliquent les idées sur lesquelles ce kit est construit : le Domain-Driven Design (stratégique et tactique), l'architecture en couches et sa règle de dépendance, la messagerie et la cohérence entre contextes délimités (bounded contexts), les préoccupations transverses, le code propre et les tests. Elles enseignent et donnent les raisons ; les règles elles-mêmes sont énoncées une seule fois, dans la référence d'architecture, et chaque page y renvoie par identifiant de règle. Chaque page se lit seule en quelques minutes. Lues dans l'ordre, elles forment un parcours de « qu'est-ce qu'un domaine » à « comment est-ce que je teste ceci », avec un seul exemple du début à la fin : une application de prise de rendez-vous.

Le parcours de lecture en six sections : conception stratégique (pages 1 à 5), conception tactique (6 à 11), architecture (12 à 15), messagerie et cohérence (16 à 22), préoccupations transverses (23 à 34), code et tests (35 et 36), chacune avec la question à laquelle elle répond

Des clients prennent rendez-vous avec des praticiens. Cinq contextes délimités sont construits, et l'identité est achetée :

Contexte Classification Possède
appointments cœur les règles de réservation, de report et d'annulation ; aucun praticien n'est réservé deux fois
availability de soutien les créneaux libres, calculés à partir des calendriers et des rendez-vous réservés
calendars de soutien les heures de travail et les absences de chaque praticien
notifications de soutien les confirmations et les rappels, par des fournisseurs de courriel et de SMS
analytics de soutien les statistiques d'occupation et d'absences aux rendez-vous
identité générique un fournisseur OpenID Connect ; aucun contexte dans le code

Comment ils dépendent les uns des autres, de l'amont vers l'aval, tels que les trouve l'exemple détaillé de la carte des contextes :

L'exemple suivi : calendars publie vers appointments et availability ; appointments, le contexte cœur, publie vers availability et notifications, et analytics s'y conforme ; le fournisseur de courriel et de SMS est en amont de notifications, qui garde une couche anticorruption ; le fournisseur d'identité émet les jetons de chaque contexte

L'application d'exemple du dépôt, examples/scheduling, est un découpage plus petit du même domaine, qui tourne ; plusieurs pages citent son code.

1. Conception stratégique : où sont les frontières

Section intitulée « 1. Conception stratégique : où sont les frontières »

Lisez celles-ci d'abord. Elles décident de tout ce qui suit, et ce sont des décisions de personnes, pas d'outils.

  1. Domaine et sous-domaines : cœur, de soutien, générique, et comment classer.
  2. Contexte délimité : ce qu'est une frontière et les tests qui en trouvent une.
  3. Langage omniprésent : le glossaire, et pourquoi il s'écrit avant le code.
  4. Carte des contextes : les patrons de relation entre contextes, quand chacun convient et ce qu'il coûte.
  5. Carte des contextes : un exemple détaillé : d'une simple expression des besoins à la carte de l'application de prise de rendez-vous.

2. Conception tactique : ce qu'il y a dans un contexte

Section intitulée « 2. Conception tactique : ce qu'il y a dans un contexte »
  1. Entités et objets-valeurs : l'identité contre la valeur.
  2. Agrégats : la frontière de cohérence, une transaction, la référence par identifiant, le dimensionnement.
  3. Briques du domaine : événement du domaine, service du domaine, repository, fabrique (factory).
  4. Invariants, permissions, validation : trois choses différentes, trois endroits.
  5. Modèle anémique : comment en reconnaître un, et quand un modèle mince convient.
  6. Machines à états : le cycle de vie d'un agrégat déclaré une fois, interrogé par l'agrégat, dessiné dans son CONTEXT.md.
  1. Couches et règle de dépendance : architecture hexagonale, en oignon et clean architecture, ce qu'elles partagent et où elles diffèrent.
  2. Ports et composition : les ports comme classes abstraites, la racine de composition, les déclarations par décorateurs ou le câblage explicite.
  3. CQRS : les bus de commandes et de requêtes tels qu'ils sont utilisés ici ; l'event sourcing est un choix séparé, par agrégat. La couche présentation va avec : une classe de contrôleur par route, les groupes de routes, les gardes à la bordure et les permissions sur le cas d'usage ; et représentations, accès aux champs et formulaires : un seul schéma servi en JSON, XML ou CSV, des champs réservés à certains appelants, des formulaires décrits par le serveur.
  4. Monolithe modulaire : un seul déployable, de vrais modules.

4. Messagerie et cohérence : comment les contextes collaborent

Section intitulée « 4. Messagerie et cohérence : comment les contextes collaborent »
  1. Événements du domaine et d'intégration : les deux sortes et ce qui les sépare.
  2. Outbox transactionnelle : pourquoi publier directement vers un broker perd ou invente des événements, et les stratégies de relais.
  3. Livraison et idempotence : au moins une fois, les consommateurs idempotents, le stockage des événements traités, l'ordre.
  4. Cohérence à terme : expliquée à une personne du produit.
  5. Sagas et gestionnaires de processus : ce que le kit fournit et ce qu'il ne fournit pas.
  6. Versionnement des événements : changer un contrat que d'autres consomment.
  7. L'event sourcing, par agrégat : quand un agrégat garde ses événements au lieu de son état, ce que cela coûte, et comment y faire passer un agrégat et l'en faire revenir.

5. Préoccupations transverses : ce qui entoure les cas d'usage

Section intitulée « 5. Préoccupations transverses : ce qui entoure les cas d'usage »
  1. Authentification et autorisation : rôles, attributs, relations, avec une table de décision.
  2. L'autorisation en pratique : @Requires, le middleware, le port Authorizer et les politiques, suivis à travers une seule commande.
  3. Acteur et portée d'exécution : qui agit, explicitement, et ce que porte chaque unité de travail.
  4. Multitenance : un seul déploiement, de nombreux clients, et aucune lecture ni écriture qui passe de l'un à l'autre.
  5. Journal d'audit : qui a fait quoi, enregistré depuis l'extérieur des cas d'usage.
  6. Observabilité : traçage, journaux, métriques, remontée des erreurs, et l'identifiant de corrélation qui les relie.
  7. Résilience : nouvelle tentative (retry), délai d'expiration (timeout), disjoncteur (circuit breaker), cloison (bulkhead), cache, et comment chacun échoue.
  8. Cache HTTP : quoi mettre en cache à quelle couche, qui peut garder une réponse, et jamais une décision d'autorisation d'un acteur à l'autre.
  9. Jobs planifiés : le travail déclenché par le temps, et pourquoi il doit être idempotent.
  10. Jobs en arrière-plan : le travail qu'un cas d'usage confie à un worker, mis en file dans sa transaction, exécuté au moins une fois.
  11. Stockage de fichiers : les fichiers dans un stockage et jamais dans la base de données, l'ordre qui garde les deux cohérents, les liens signés.
  12. Import et export de fichiers : une conception, pas encore construite : un gros fichier lu ou écrit par un job en arrière-plan, ligne par ligne, entre la file d'attente et le stockage de fichiers.
  1. Code propre : nommage, petites fonctions, lecture en descente (stepdown), commentaires, testabilité par construction.
  2. Stratégie de test : des fakes plutôt que des mocks, des builders, des tests de contrat, les quatre niveaux.
  • Une personne du produit ou un nouveau venu au DDD : 1, 2, 3, 5, puis 19.
  • Avant d'écrire un premier cas d'usage : 3, 7, 9, 12, 14, 36.
  • Avant de faire dialoguer deux contextes : 4, 16, 17, 18, 21.
  • Avant de garder un agrégat sous forme de ses événements : 7, 16, 17, 21, 22.
  • Avant de servir plusieurs clients depuis un seul déploiement : 23, 25, 26.
  • Avant de mettre le système en production : 23, 24, 28, 29, 30, 31, 32, 33, puis les pages d'outils.

Ces pages décrivent une façon assumée (opinionated) d'appliquer les patrons : celle que ce kit impose. D'autres applications valables existent (l'event sourcing, une base de lecture séparée, des agrégats persistés comme documents), et plusieurs pages disent où le kit s'arrête. Les patrons eux-mêmes ont un coût : pour un petit outil avec peu de logique métier, l'essentiel des sections 2 à 4 dépasse ce que le problème demande, et chaque page a une section « Limites et quand ne pas l'utiliser » qui le dit dans ses propres termes.