This post is about my DDD training with Eric Evans and Zenika in Paris. It might not be translated perfectly to English, I apologize if you’re reading this through Google Translate. But anyway, enjoy and try to see what’s happened during those 4 days.
Je résume dans cet article les 2 derniers jours de la formation d’Eric Evans sur Domain Driven Design. Après une première journée de sensibilisation, une deuxième journée pour comprendre les outils de modélisation, nous allons voir comme nous avons avancé dans notre immersion dans l’univers DDD.
Au matin du 3ème jour, les esprits sont encore un peu secoué de la veille. La notion d’Aggregate est discutée, nous nous apercevons qu’elle a toujours un noeud de départ, souvent une Entité. Cela résonne tout d’un coup dans ma tête lorsque je défile rapidement la liste des projets de ces dernières années. Le pattern « Aggregate » résonne encore lorsque l’on tente de parler de SOA. Il s’avère que la majorité des applications est une intégration continue d’applications existantes, plutôt qu’une intégration de services. Chaque projet, chacune des équipes dans votre département travaille sur un projet différent. Ce projet est un Context, un espace délimité, un organisme à part entière. Il communique avec le monde extérieur, mais dans son espace de droit, ce que l’on appelle le « Context » en DDD, son modèle est roi.
Pour qualifier plus précisément un Context, Eric présente les « Context Map ». Lorsque SOA est correctement utilisé, c’est un moyen d’isoler le domaine de votre application. La notion de Domain est difficile à comprendre, c’est pourtant le coeur des idées derrière DDD. Eric explique que le Domaine a été mis parfois au second plan lors des années Internet. Cela nous a peut-être trop éloigné des utilisateurs, des clients et des personnes qui définissent la raison d’être d’un logiciel (le « What« ). Nous nous sommes trop engagé dans la voie du « How« , sur les solutions techniques, comme des alchimistes à la recherche de la formule de la transmutation du plomb en or.
Revenons dans les années EJB 2.1 et regardons ce qu’il s’est passé pour ne pas recommencer. Nous nous sommes embarqués dans des architectures pilotées par un standard, où il était plus important de connaître les patterns J2EE pour être embauché, que de montrer ses capacités d’abstraction et de modélisation du domaine. Embourbé dans du code de framework, la communication avec les vrais propriétaires du Domaine s’est dégradée.
Pour revenir à la formation, Eric Evans présente ensuite quelques principes faciles à observer. Tout les grands systèmes ne sont pas correctement désignés. Pour pouvoir en sortir la vraie valeur, Eric aborde la notion de « Core Value« . C’est une notion très simple qui va nous aider dans quelques minutes à découper notre modèle. Il existe 3 types de domaines, 3 types de valeurs pour les fonctions de votre logiciel:
– Generic Subdomain
– Supportging subdomain
– Core subdomain
Si vous voulez faire l’exercice chez vous, voici comment faire : dessinez votre SI ou votre projet sur une feuille. Représentez les différentes fonctions clés de votre application avec une bulle. Par exemple imaginons une application qui vous permet de chercher des places de concert sur Internet. Elle serait composée de quelques modules comme : « Recherche de places », « Reservation » et « Facturation ».
Dans la catégorie Generic il s’agit de classer toutes les parties de votre application qui ne sont pas stratégiques et qui peuvent être externalisée. Dans notre exemple, la Facturation est un module que nous pouvons intégrer d’un logiciel tiers, ou faire appel à une plateforme Web. Et notre métier est de chercher des places, pas de coder un module de facturation. Donc Generic regroupe ce qui n’est pas le coeur de votre domaine. Si cela n’ajoute rien à la stratégie de l’entreprise, alors pensez à externaliser.
Dans la catégorie « Supporting » nous regroupons les fonctions intéressantes et importantes pour votre domaine, que vous allez développer, mais qui font parties de ce que doivent avoir votre application, sans valeur ajoutée. Par exemple la partie Réservation dans mon exemple.
Enfin dans la catégorie « Core Domain » nous regroupons les domaines qui sont critiques pour votre projet, pour votre système. Il s’agit réellement des éléments qui doivent être présents pour que le projet réussisse, et qui doivent apporter le plus de valeur. Ce sera par exemple la recherche optimisée de place, avec un algo très compliqué et très rapide.
Le simple fait de classer ces domaines donne tout de suite une vision stratégique de votre application. Et ce mot stratégique va revenir plus vite que l’on ne le pense dans la conversation.
Il convient ensuite de travailler sur les frontières entre ces domaines, et à identifier les flux entre les domaines. Si vous vous demandez ce qu’est un domaine, voici la définition en Français d’Eric:
« Un domaine est une sphère de connaissance, d’influence et d’activité. Le sujet d’application auquel l’utilisateur applique un programme est le domaine de ce logiciel. »
Quant à définir un modèle, voici ce que l’on peut dire:
« Un Modèle est un système d’abstractions qui décrit certains aspects d’un Domaine et qui peut être utilisé pour résoudre des problèmes reliés à ce Domaine« .
Lorsque votre tableau blanc est rempli de rond, de flèches et de diagrammes, il est alors temps d’isoler et de poser des frontières propres, ce que l’on appelle « Bounded Context » dans le jargon DDD. Nous avons ensuite effectué plusieurs exercices en groupe, en identifiant les relations entre les différentes équipes d’un projet virtuel. Il s’avère que cette partie m’a particulièrement intéressé, c’est le domaine du Strategic Design de DDD.
Le Strategic Design est simplement un ensemble de Patterns qui permettent d’identifier les stratégies de relation entre différents domaines, entre différentes équipes. Avec les patterns présentés, nous arrivons en quelques heures à définir les relations entre un fournisseur de service, un intégrateur, des équipes tiers, bref à créer un schéma stratégique pour comprendre les relations entre les Domaines.
Par exemple pour expliquer la notion de « Upstream/Downstream » Eric utilise une image assez parlante. L’exercice est de dire quelle est l’équipe qui affecte le travail d’une autre équipe. Pour identifier ce qui est Upstream, pensez à une ville sur un fleuve. Celle-ci pollue l’eau du fleuve. Une autre ville située en aval reçoit de l’eau polluée, c’est donc elle qui est affectée. Plus important, les actions de la ville en Aval n’affecte pas la ville en amont. Rapporté au développement logiciel, voici comment cela se traduit : vous utilisez une API ou un service d’une équipe tierce, mais celle-ci n’a pas connaissance de votre existence, vous êtes donc dans une certaine situation identifiée par DDD avec des Patterns.
Pour faire face à cela, les équipes développent des Stratégies. Il en existe plusieurs que nous avons étudié. L’une d’elle est « l’Anticorruption-Pattern ». C’est une stratégie défensive où l’équipe en aval met en place des filtres lorsqu’elle intègre des données provenant d’une autre équipe, car elle n’a pas confiance en elle, ou elle n’a pas la possibilité de faire remonter ses problèmes. De manière très concrète, dans l’équipe Primeweb où j’ai travaillé, nous avions des outils d’intégrations et de transformations très compliqués… car nous avions peu d’influence sur nos fournisseurs de données.
Cela me fait penser à la loi de Melvin Conway qui date de 1968 :
…organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations.
En clair : un logiciel A ne peut pas s’interfacer correctement avec un logiciel B et inversement s’il n’y a pas de communication entre le développeur du logiciel A et celui du logiciel B, ce qui tend à montrer que les architectures informatiques sont souvent le reflet des relations des équipes dans le monde réel. Bref allez ouvrir la porte, allez voir vos voisins, prenez des bières avec eux, et votre architecture n’en sera que meilleur.
La fin de la troisième journée a été consacrée à quelques jeux de rôles afin de découvrir les différents patterns stratégiques. Cette partie de DDD était pour moi inconnue. Et j’ai appris réellement de nouveaux concepts qui me serviront dans ma vie d’Architecte sur le terrain. C’est aussi pour cette raison que la formation s’adresse, à mon avis, plus à des Seniors avec un peu de bouteille. Il faut avoir vécu du projet bien pourri, avec des clients psychopathes réfugiés derrière une spécification pour apprécier DDD et cette partie (ce que je n’ai pas eu la chance de rencontrer bien entendu soit dit en passant).
Dernière journée
La dernière journée a été un peu longue à mon avis. Il y a eu quelques nouvelles notions, quelques retours sur les 3 derniers jours, et aussi un après-midi sympa avec encore de nouvelles idées d’Eric. Nous reparlons de la notion de Contexte et de son importance dans notre travail. Il est important de définir le Contexte dans lequel un problème s’applique. Un contexte est un ensemble fermé dans le vocabulaire est important, où chaque mot est défini sans ambiguité. La notion de langue dérive ensuite vers une explication des DSL. Il présente la notion d’Internal et d’External DSL, avec un exemple de librairie sur le temps. Les outils appris ces derniers jours ne servent pas tous, quoique le Value Object prend toute sa valeur pour présenter quelques idées.
Olivier un lecteur a mentionné le framework « Sculptor CSC « . C’est un outil de génération basé sur un plugin Maven, qui utilise les patterns DDD pour construire une application complète avec Hibernate, Spring et autre.
Prenez par exemple ce DSL :
Application Library { basePackage = org.library Module movie { Service LibraryService { findLibraryByName delegates to LibraryRepository.findLibraryByName; saveLibrary delegates to LibraryRepository.save; findMovieByName delegates to MovieRepository.findByName; } Entity Library { String name key reference Set<@Movie> movies Repository LibraryRepository { save; @Library findLibraryByName(String name) throws LibraryNotFoundException; protected findByCriteria; } } Entity Movie { String title not changeable String urlIMDB key Integer playLength Repository MovieRepository { List<@Movie> findByName(Long libraryId, String name) delegates to FindMovieByNameAccess; } } } }
Sculptor est capable de construire une application en utilisant cette description de l’architecture, avec les Patterns DDD. Pas mal non ?
Pour continuer ensuite, j’ai noté quelques phrases distillées par Eric durant la suite de la journée. En voici une sélection :
Ce qui fait notre valeur de développeur ce n’est pas notre capacité à réaliser, mais notre capacité à comprendre un domaine puis à l’implémenter (E.Evans february 2010)
En bref : cela ne sert pas à grand chose d’être une brute en Java, si tu n’es pas capable de comprendre ce que veut le client, si tu n’arrives pas à transcrire en Java ce qu’il t’a demandé, et si tu n’arrives pas à parler sa langue. Du coup j’ai envie de laisser cette phrase pour qu’elle soit reprise un jour sur un slide par un gars dans 10 ans :
« Un bon développeur sait coder. Un très bon développeur sait à la fois écouter, comprendre et coder. Et une brelle ne sait rien faire de tout cela »
Pour suivre cette idée, il explique que lorsque les gens découvrent la programmation orientée objet, ou la modélisation UML, ils ne se rendent pas compte que le plus dur est de faire de bonnes abstractions.
Qui n’a jamais vu des trucs bien bizarre dans des diagrammes UML comme « DialogueUtilisateur » ou « Curser de Base de Données » ? L’abstraction sans intelligence est dangereuse.
Pour réutiliser des termes DDD, Eric dit que notre capacité à utiliser Hibernate est dans la catégorie « Supporting ». Par contre, comprendre correctement un problème financier est dans la catégorie « Core » de nos capacités.
Après un repas bien français (rillettes, Civet de Biche « Bambi » et choux à la crème chantilly) nous reprenons la dernière ligne droite. Le sujet de l’après-midi est intéressant, car il met à mal quelques dogmes du monde Java. Nous parlons de la différence entre les DTO et les ValueObjects. Sur le papier, c’est la même chose. Mais là encore, si nous appliquons le « Contexte » nous voyons que les DTO sont des objets de transports, souvent plus simple que des ValueObjects, objet à valeur ajoutée, capable d’effectuer des opérations.
Eric aborde la notion de Repositories, qui est proche du DAO avec de l’intelligence en plus. Un Repository est un moyen d’accès pour le client à des objets du domaine. Il s’agira toujours d’accéder aux Entités racines de votre modèle. L’accès aux feuilles se fera au travers des Entités racines. C’est assez délicat à expliquer et je pourrai y passer la nuit, alors je vous propose une synthèse. Pour chaque type d’objet qui a besoin d’être accédé globalement, créer un objet qui donne l’illusion d’une collection en mémoire de tous ces objets. Jusqu’ici, c’est un DAO. Ajoutez uniquement les méthodes de création, modification et effacement lorsque c’est nécessaire. Par rapport à un simple DAO crud, un Repository sera capable de charger des graphes d’objets complets, de proposer des Query avancées en rapport avec le domaine, et qui masquera la stratégie d’implémentation.
DAO et Repository effectuent la même chose, un accès tardif à la donnée, en donnant l’illusion qu’elle est en mémoire alors qu’elle est dans une base par exemple. Un DAO est un pont pour chaque Entité, alors qu’un Repository est un super-pont qui n’est mis en place que sur les Entités racines, en étant capable d’accéder aux entités filles, via l’entité racine. Il faut aller fouiller dans la littérature pour voir vraiment la différence, mais on rencontre les DAO avec des bases relationnelles, alors que le pattern Repository est plus global.
Dans les différentes discussions, nous parlons aussi de la notion de « Command-query separation » décrite par Bertrand Meyer l’auteur du langage Eiffel.
It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer. More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.
Une discussion intéressante ensuite sur la notion de SOA. Eric explique qu’un Service dans l’absolu est simple à définir. C’est un machin qui envoie et qui reçoit des bytes, ni plus, ni moins. Ce qui en fait sa valeur, c’est le contexte, c’est le métier pour lequel il a été développé. Eric parle de « meaningfulness parameters » ou paramètres de pertinence.
Une question est posée : que se passe-t-il si vous ignorez le Design trop longtemps ? Eric retourne la question en nous demandant si nous pouvons travailler en ignorant le domaine d’application. Prenez un projet dans la finance de génération de rapports financiers, dont le nom commence par Prime… Bon bref vous voyez… J’ai vraiment apprécié les formations sur le domaine que nous avons fait à la fin du projet lors du passage de connaissance. Je regrette de ne pas avoir fait plus tôt ce travail. Promis je ne recommencerai pas. Etre architecte sans comprendre le domaine, c’est mal.
Au début vous savez que vous ne savez pas. Le problème de ne pas savoir, c’est que votre code et plus particulièrement votre architecture va être simpliste. C’est pour cette raison qu’il faut trouver des experts du domaine. Essayez de poser des questions avec « Pourquoi » et « Comment ». En apprenant le domaine, vous allez itérer sur votre modélisation, sur votre modèle. En fait, un bon modèle sera adapté toutes les 2 semaines environ. C’est aussi pour cela que je ne crois pas à la modélisation upfront.
Enfin pour terminer, Eric nous montre ses derniers travaux. Il travaille sur la modélisation d’un processus pour mettre en place DDD dans l’entreprise. Il explique que ses dernières années l’ont conforté dans sa vision de 2004. Le livre est une référence, un instantané, un ouvrage qui sera lu encore dans quelques années. Il en a vendu plus de 25 000, ce qui est beaucoup pour un livre d’informatique. C’est une personne humble mais particulièrement forte, qui distille des idées sur notre métier. Cette idée de stratégie et de pattern est brillante. Elle va me permettre de comprendre comme un schéma tactique ce qui se passe sur un projet.
Dans les regrets, il y a eu quelques longueurs durant la formation, où l’on décroche. Le rythme est un peu lent. Dans les trucs marquants, c’est cette capacité à présenter des concepts simples et puissants.
Je conseille la formation aux Architectes en hibernation, aux bons développeurs à la recherche d’une nouvelle philosophie de développement. J’ai apprécié cette formation grâce à mes expériences passés, en tant que développeur ou chef de projet. De nombreux patterns stratégiques résonnent car j’ai vécu ces situations. La partie Modèle à proprement parlé me rassure aussi sur la vision de notre métier. Ouf, tout n’est pas que technique, framework et sauce de geek. L’interaction avec le client et la définition du modèle sont plus importants dans la philosophie Domain Driven Design.
Voilà, si cela vous tente, je crois qu’Eric Evans reviendra chez Zenika. Il y a aussi Greg Young en mars qui vient faire une formation chez OCTO Technology. Comme cela je fais de la pub pour tout le monde, y’a pas de jaloux.
Merci à Zenika pour ces 4 jours rafraîchissants !
A bientôt.
J’aime entendre dire que l’architecture ce « n’est pas que technique, framework et sauce de geek ». Merci pour ce retour d’expérience, cela m’a permis de découvrir le DDD ce qui me conforte dans ma manière de penser une architecture.
Merci Nicolas pour ces 3 excellents billets.
J’ai eu la chance également d’assister à cette formation d’Eric Evans et je trouve que ta synthèse est vraiment pertinente et complète.
Je rejoins ta remarque sur les pré-requis de cette formation. Il faut avoir vécu des modèles d’entreprises pour l’apprécier à sa juste valeur.
Merci pour ce compte rendu complet!