Publié par
Il y a 9 années · 9 minutes · Craft, Divers, Events

DDD – La conception qui lie le fonctionnel et le code

Le DDD, Domain Driven Design, laisse une impression qui amène souvent à une des remarques suivantes :

  • J’en ai déjà entendu parlé …(mais je ne sais pas ce que c’est)
  • Je crois l’avoir vu dans le TDD …
  • C’est comme le MDA?ça marche avec un ensemble de sigles MDSD, MDD
  • Hein? T’as un problème avec ta touche « D »

L’objectif de cet article est de vous présenter le DDD, ses enjeux et son intérêt.

Dans DDD, il y a Driven Design, c’est donc une technique de conception. Il ne faut pas confondre avec les techniques de développement (Driven Development) comme par exemple le TDD (Test Driven Development).

DDD n’est ni une méthode ni une technologie. DDD est une manière de penser la conception autour du code, de collaborer et de communiquer avec les experts fonctionnels.

Cet élément de communication est une dimension importante. C’est pourquoi nous aborderons dans cet article les thèmes suivant :

Qu’est ce que la conception logicielle

Une définition

La conception logicielle soulève de nombreuses questions. Dans le cadre de notre article, la conception peut être considérée comme une manière de concevoir et d’implémenter un ensemble de fonctionnalités en respectant un ensemble de considérations.

Il existe de nombreuses considérations plus ou moins importantes suivant les contextes et les organisations : Adaptabilité, coût, compatibilité, maintenabilité, modularité, performance, productivité des développements, qualité, réutilisabilité, robustesse, sécurité, simplicité, testabilité, ergonomie, utilisabilité, …

Il faut donc choisir les considérations et les prioriser afin d’orienter la conception. La conception peut imposer de mettre en place une méthode (processus, livrable, formalisme) et/ou des techniques afin de concrétiser la conception lors de l’implémentation en code source.

Pourquoi concevoir?

Au fil du temps, les progressions technologiques nous ont permis de construire des programmes de mieux en mieux structurés. Programmes qui d’ailleurs eux aussi évoluent vers des logiciels au fonctionnement de plus en plus complexes. Nous avons donc évolué de l’assembleur au Java en passant par le C et le C++. Aujourd’hui, afin de construire des applications de gestion, il est commun d’utiliser un langage qui implémente les concepts de la programmation orientée objet (POO) comme Java ou C#.

Afin de prendre en compte la complexité croissante des applications, il faut avoir un plan d’actions de développement avec une conception.

Le chemin est long entre les fonctionnalités demandées et décrites dans un logiciel et l’implémentation avec le paradigme objet et un langage OO. Il y a énormément de liberté pendant la phase conception. La POO ne nous guident pas assez lors de la conception.

Ainsi, avec un tel modèle, les techniques de conception de la POO ne garantissent pas une bonne conception, il faut donc des concepteurs très talentueux !

Qu’est ce qu’une bonne conception?

En premier lieu, une bonne conception permet de développer un logiciel qui répond aux fonctionnalités demandées. Idéalement, elle permet l’évolution et la maintenance du logiciel. Les évolutions ne doivent pas remettre en question toute la conception et l’implémentation. Une bonne conception est un ensemble de considérations comme par exemple la flexibilité, la robustesse ou la maintenabilité suite à des évolutions et des corrections.

Pour tendre vers une bonne conception, une stratégie est de découper l’application en modules en suivant la règle « diviser pour mieux régner ». Ces modules suivent des règles à respecter :

Il existe de nombreux travaux et ouvrages sur la conception de personnes reconnues comme expert dans le domaine comme Bertand Meyer, fondateur du langage objet Eiffel, Robert C. Martin, ou encore Martin Fowler. Leurs travaux sont résumés dans le document Principes avancés de conception objet.

Présentation du DDD

Le DDD a été introduit par Eric Evans en 2003. Il a construit cette approche de conception suite à des retours d’expérience. Le DDD est centré sur le métier de l’application et le code source qui l’implémente.

Si vous êtes prêts à suivre les prédicats suivants :

  • Vous vous préoccupez du domaine métier et de sa logique,
  • La complexité du domaine métier devrait se refléter dans le modèle.

Le DDD vous aidera :

  • En développant des applications investissant sur le métier du SI,
  • En donnant une expressivité métier à votre code source,
  • En faisant communiquer les développeurs et les experts fonctionnels,
  • En vous fournissant des techniques de conception (pattern du DDD, refactoring continu),
  • En vous proposant des solutions pour organiser une équipe de développement et même un ensemble d’équipes de développement qui collaborent entre elles.

Le DDD est une manière de penser et de communiquer les problèmes et leurs solutions, entre les équipes techniques et fonctionnelles.

La conception est conduite par un modèle. Ce modèle est en partie constitué d’un langage de communication commun aux experts fonctionnels et aux équipes de développement.

Les avantages d’avoir un Domain Model sont :

  • Créer un modèle commun et intelligible entre les équipes fonctionnelles et les équipes techniques
  • Le modèle est modulaire, flexible et maintenable car il doit refléter la conception fonctionnelle
  • Améliorer la testabilité et la réutilisation des objets métiers.

Cela conduit aussi les équipes de développement à investir sur le fonctionnel des applications d’entreprises.

Comprenons le fonctionnel et communiquons avec ses termes

Il faut tout d’abord que les développeurs se familiarisent avec le fonctionnel. Pour cela il faut une communication privilégiée entres les développeurs et les fonctionnels :

  • Un langage de communication (commun),
  • Des lexiques de termes métier.

On dit que l’on forme l’Ubiquitous Language.

Ces termes se retrouveront tels quels dans le code source. De manière générale, les développeurs doivent apprendre et monter en compétence sur le fonctionnel afin de concevoir au mieux le domaine métier des applications.

Le DDD n’impose ni formalisme ni méthode pour acquérir ce savoir. L’interview d’expert fonctionnel par des développeurs peut être une solution. La communication entre ces deux entités doit être continue tout au long du projet.

Ce modèle apporte donc aux applications développés avec le DDD :

  • La communication (et donc la connaissance partagée)
  • La maintenabilité
  • La simplicité
  • La réutilisabilité

Un langage de communication commun

Il existe des incompatibilités de vocabulaire entre les développeurs et les experts fonctionnels :

  • Un développeur parle avec des termes techniques :
    • algorithmes,
    • paradigme objet (objet, encapsulation, héritage, polymorphisme),
    • méthodes,
    • Design Patterns,
    • Framework, libraires.
  • L’expert fonctionnel ne connait pas ces termes, et il n’en a pas besoin pour réaliser son travail. Il est compétent sur le domaine fonctionnel.

Il faut un langage commun de communication entre ces deux types de population. Il faut créer un Ubiquitous Language. Ces termes se retrouveront directement dans le Domain Model et donc dans le code source.

Il y a des pièges à éviter. Par exemple, si les spécifications sont en français et que les conventions de nommage des artefacts de programmation sont en anglais, différentes erreurs peuvent survenir :

  • mauvaises traduction de la spécification à l’implémentation (nom des classes, méthodes, etc)
    • traductions ambiguës,
    • traductions erronées,
    • traductions dupliquées,
    • etc.

Les développeurs doivent réutiliser le jargon des experts fonctionnels dans leurs explications et dans le code source.

Ce langage de communication permet :

  • Construire et cultiver un langage commun : en interviewant les experts fonctionnels par exemple,
  • Capturer la connaissance du domaine fonctionnel,
  • Distiller le modèle : « dé-scoper » ce qui n’est pas primordial dans la conception du modèle, revenir dessus lors d’une prochaine itération,
  • Produire le code, reboucler avec les experts fonctionnels pour enrichir le modèle avec des termes qui ont dû être explicités lors du développement

A venir

Les choses importantes à avoir en tête lorsque l’on parle du DDD sont :

  • DDD n’est ni une méthode ni une technologie, c’est une manière de penser la conception autour du code source,
  • Le modèle du DDD est composé d’un langage de communication, d’une conception et de son implémentation,
  • Ce langage de communication doit être intelligible, partagé, adopté et enrichi par les développeurs et les fonctionnels. Pas de transformation de langage, ne rajoutons pas de difficultés,

Vous l’aurez remarqué, le DDD est une approche de conception non intrusive, mais ne résout pas tous les problèmes. Cela a pour grand avantage d’avoir une manière de concevoir flexible et évolutive tout en respectant un certain nombre de pratiques déjà adoptées et éprouvées dans vos équipes. Par exemple, elle peut être associée à UML et/ou TDD sans que cela soit une obligation.

De plus, le DDD ne nécessite pas d’atelier logiciel particulier, n’impose pas de formalisme et n’impose pas non plus de méthode de développement.

Dans un prochain article nous verrons comment concevoir une application avec les techniques proposées par le DDD.

Références à ne pas manquer à propos du DDD :

10 réflexions au sujet de « DDD – La conception qui lie le fonctionnel et le code »

  1. Publié par Alexandre de Pellegrin, Il y a 9 années

    Merci pour cet article. Pour autant, je me demande comment un équipe de développement peut s’engager sur une implémentation sans avoir saisi le métier de son client. Il est d’ailleurs communément reconnu qu’en fin de projet, le développeur connait mieux le métier que l’utilisateurµ. Normal : le développement ne permet pas de laisser de zones d’ombre. Pour moi, adopter le DDD, c’est bien sûr poser le modèle métier. Enfin ça, on le fait déjà depuis pas mal de temps (même avant Merise.) Mais le DDD, c’est aussi donner le comportement métier du modèle. Cela se traduit notamment dans le code par l’écriture de classes non anémiques. Petit bémol tout de même, seul le coeur de code est concerné. Tout le reste (en dehors d’un package ‘domain’ par exemple) conserve sa forte technicité.

    Alex dP

  2. Publié par Fabien Bézagu, Il y a 9 années

    Je suis ravi de constater qu’il se passe des choses autour de DDD. Je profite de l’occasion pour faire un peu de communication autour d’un site que je suis, avec des amis, en train de lancer doucement : http://www.dddfrance.org . Pour l’instant, le contenu est limité mais nous avons créé un site dont le principe est d’être enrichi par les expériences et les questions de chacun.

  3. Publié par Karim, Il y a 9 années

    Bonjour Nicolas, je trouve ton article très intéressant mais trop scolaire ;-).
    J’ai du mal a saisir tes enjeux, j’aimerai bien les connaitre.
    Demain je rencontre un client, pourquoi son chef de projet accepterait ce type d’architecture……
    Certes tu as mis en évidence l’élément le plus fondamentale Ubiquitus Language mais ta façon d’y arriver se fait un cheveux sur la soupe.
    Ensuite je trouve que ton article s’adresse vraiment aux initiés
    Beaucoup de personnes autour de moi ont du mal à voir la différence avec le MDA.
    Ton article manque d’exemple concret, tu reste trop en surface pour moi.
    Je me permet d’être très critique sur ce sujet dans la mesure ou tu souhaites t’adresser aux non initiés, et que le sujet est extrement ambitieux.
    Par contre ayant l’expérience de projet, je nuancerais ce propos lorsque tu écris que le DDD marche avec toute méthode.
    Les modèles métiers deviennent de plus en plus complexe, la seule façon d’y arriver consiste à travailler avec une approche itérative.
    Si tu travailles sur des projet en cascade, le risque sera de faire du DDD en mode conceptuel……
    A bientôt content de rejoindre ton club DDD
    Cordialement Karim

  4. Publié par Nicolas Lecoz, Il y a 9 années

    Bonjour,

    Alexandre, merci pour ces précisions. En effet, une idée des fortes du DDD est la communication CONTINUE sur le fonctionnel tout au long du projet. Ainsi les équipes de développements et fonctionnelles doivent avoir la même connaissance à la fin des développements. Les équipes de développement ne doivent pas laisser de flou sur une implémentation de fonction et remonter toutes ces informations aux experts fonctionnelles. Sinon au fil de développement on a une version « papier » du logiciel, et une version « code » du logiciel, ce qui amènera beaucoup d’interrogation sur le fonctionnement du logiciel et décrébilisera le logiciel et ses équipes.

    Fabien, belle initiative et je te souhaite que ça marche. Pour informations Eric Evans a entrepris une initiative semblable http://dddsample.sourceforge.net/.

    Et pourquoi implémenter leur exemple avec Qi4J ! ;-). As-tu des expériences avec ce framework, Sébastien?

  5. Publié par Nicolas Lecoz, Il y a 9 années

    Bonjour Karim,

    Toutes les remarques et les critiques sont les bienvenues, voici les réponses et les éclaircissement de divers points :

    > Demain je rencontre un client, pourquoi son chef de projet accepterait ce type d’architecture……

    Pourquoi une entreprise voudrait utiliser le DDD? Pour développer des applications qui investissent sur son métier. Pour être plus précis, il veut développer des applications qui lui permettent d’implémenter son métier et de mieux comprendre son fonctionnement dans un contexte de logiciel. Par exemple il doit adapter son métier historique au monde de l’e-commercre : vendre sur Internet et vendre en magasin présente chacune des spécificités fonctionnelles. Le DDD peut être une bonne manière de montée en compétence sur ce point.
    De plus, il ne veut plus avoir des applications qui sont écrites un instant T et qui 2-3 ans plus tard sont refaites parce que l’on a perdu la cohérence entre ce qui est défini entre les spécifications fonctionnelles et l’implémentation. On se retrouve parfois à réécrire des applications parce que l’on ne sait plus ce qu’elles font réellement.
    Enfin, le DDD encourage les équipes techniques et fonctionnelles à travailler ensemble et à s’améliorer ensemble. Ces équipes seront un atout plus tard sur les autres projets.

    > Certes tu as mis en évidence l’élément le plus fondamentale Ubiquitus Language mais ta façon d’y arriver se fait un cheveux sur la soupe.

    Comme j’ai insisté dans cet article, le DDD a des techniques non intrusives et doivent d’adapter aux organisations existantes. Ainsi il est difficile de dire comment les organisations existantes doivent faire pour communiquer entre elle. J’ai juste fait des propositions afin de « capturer la connaissance fonctionnelle » comme l’interview d’expert fonctionnel par les équipes techniques, des lexiques des termes métiers …
    Si tu as un retour de terrain, cela intéresse les lecteurs afin qu’il ait une meilleur compréhension de comment y arriver.

    > Beaucoup de personnes autour de moi ont du mal à voir la différence avec le MDA.

    Oui c’est assez déroutant tous ces acronymes consonants et qui cachent des concepts fondamentalement différents. Pour te révéler les secrets de fabrication de l’article, à l’origine l’article s’appeler « les faux amis du DDD : TDD, MDA, MDD, MDSD, … ». En discutant en interne de Xebia, le sujet de l’article n’était pas approprié car le sujet reste le DDD. Je reinsiste sur la définition que j’ai proposé : « DDD est une manière de penser la conception autour du code, de collaborer et de communiquer avec les experts fonctionnels ». Tandis que le MDA se base sur des modèles et heuristiques afin de générer le code source de l’application. Même si les prédicats peuvent être semblable la démarche est totalement différents. En DDD, l’implémentation est toujours réalisée par les développeurs. En MDA, l’implémentation est en partie délégué à des outils. Ce qui est déroutant en DDD c’est que ce fameux modèle n’a rien à voir avec un modèle MDA.

    > Ton article manque d’exemple concret, tu reste trop en surface pour moi.
    > Je me permet d’être très critique sur ce sujet dans la mesure ou tu souhaites t’adresser aux non initiés, et que le sujet est extrement ambitieux.

    Je vais proposer une série d’article 2 ou 3 (je ne sais pas encore). Le 2è article sera consacré à un exemple : « Dans un prochain article nous verrons comment concevoir une application avec les techniques proposées par le DDD ». Je n’ai pas pour ambition de supplanter la référence qui reste les travaux d’Eric Evans (son livre, son site http://domaindrivendesign.org/, et son site d’exemple http://dddsample.sourceforge.net/.).

    > Par contre ayant l’expérience de projet, je nuancerais ce propos lorsque tu écris que le DDD marche avec toute méthode.
    > Les modèles métiers deviennent de plus en plus complexe, la seule façon d’y arriver consiste à travailler avec une approche itérative.

    Je suis entièrement d’accord avec toi. Comme dit plus haut le DDD n’est pas intrusif donc il n’impose pas de méthode de travail même si la manière de pensée du DDD se rapproche fortement de la pensée agile.

    En espérant avoir pû t’éclairer sur différents points, Nicolas LC (Xebia).

  6. Publié par louis gueye, Il y a 9 années

    Félicitations à l’auteur de l’article.

    Expliquer ce qu’est un design orienté domain model n’est pas aisé du tout.
    C’est plus de l’ordre du bon sens c’est pour cela que ce n’est pas simple à formaliser.
    Tant que l’on ne perd pas de vue que son but est la capture du fonctionnel par différentes pratiques de coding, on est bon.

    En capturant la totalité du fonctionnel dans le code on réalise le programme ‘parfait’ du point de vue d’un développeur car ça apporte une valeur inestimable en terme de compréhension, donc de reprise de code à des fins de refactoring (un code est amené à bouger car il reflète le changement du business et le niveau de compréhension du business à un instant T).
    Comme la perfection n’existe pas il existe des pratiques qui vont nous permettre de l’approcher.

    L’exercice consiste à se poser ces questions de façon récurrente :
    – mon domain model reflète-t-il assez le fonctionnel ?
    – mon domain model est-il indépendant de ma stratégie de persistance ? (ma stratégie de persistance peut changer : SGBD, mémoire vive; les requis fonctionnels doivent subsister)
    – mon domain model est-il portable dans un autre langage objet ? (java, c++, c# ; les requis fonctionnels doivent subsister)
    – mon domain model reflète-t-il les cas d’utilisation de facon exhaustive ? (La façade de mon application fait partie de mon domain model et doit comporter toutes les méthodes représentant des use cases : savePreferences, updateBalance, deleteAccount, cancelAndReplaceForFolderClosing (même si en interne c’est une méthode générique qui est appelée avec des paramètres différents)).

    Il faut différencier les unités de code qui existent à cause d’un besoin technique (remoting, technologie objet, persistance) de celles qui sont présentes quel que soit l’environnement technique. Il faut faire cet exercice mental d’épuration. On dégage ainsi le véritable fonctionnel (le noyau) et on s’y consacre.
    Exemple :
    L’interface graphique n’appartient pas au domain model, c’est juste la représentation graphique (plus ou moins user friendly) requise par le projet. Les interfaces client lourd, ligne de commande ou web sont totalement interchangeables du point de vue domain model. Elles appèleront la façade en back-end.
    Les fonctionnalités graphiques, aussi avancées soient-elles, aident l’utilisateur à utiliser l’applicatif, elles ne définissent pas ce que l’applicatif fait réellement.

    La pratique la plus basique de domain modeling est le nommage des entités de code (classes, attributs, méthodes) et l’organisation du code orienté fonctionnel et non technique (nom de package com.company…..user, com.company.accountmonitoring.balancemanagement, etc).
    Ainsi les unités de code du domain model ne devraient avoir aucune dénomination technique de type DAO, Service, Manager, Interface, etc. Ces classes n’appartiennent pas au domain model, elle assurent des fonctions techniques : persistance, exposition en remoting (EJB, Webservice, RMI pur, etc), utilisation du queueing pour notifier.
    Par contre une méthode de type getUsersWithFullNameAsDefaultSort() sur la facade pourrait représenter un requis précis de l’application.
    Exposée en remoting ou pas, utilisée par un client graphique ou pas elle est exploitable. de plus elle révèle plus de choses sur ce qu’elle fait réellement (cf Intention-Revealing Interfaces and methods).
    Cette pratique va participer à refléter au maximum le fameux ‘Ubiquitus Language’ d’Eric Evans.

    La 2ème pratique est la réflexion autour de la collaboration entre objets, la cardinalité (caractère obligatoire ou pas), la notion d’ordre, la notion d’unicité (qui se traduira en List, Set, Map, etc), les notions de composition (telle entité n’a pas de raison de vivre sans telle autre), d’héritage, de typage.

    La 3ème pratique, qui suit le nommage est l’enrichissement en comportement.
    Un vrai domain model comporte des classes TRES enrichies en comportement.
    En effet si une classe n’est écrite que pour définir des getters et setters elle est pauvre. Sa richesse est définie par les comportements (méthodes) qu’elle expose (éviter les ‘anemic domain model’ d’après Martin Fowler ).
    Si une classe a toutes les informations pour définir un comportement, c’est de sa responsabilité de le faire. On fait de l’objet, autant profiter de sa puissance.

    Un use case complexe fera participer plusieurs entités à sa décision.
    ServiceX {

    Collaborator collab1;
    Collaborator collab2;
    Collaborator collab3;

    public EntityZ intentionRevealingMethod() {

    if (!collab1.intentionRevealingMethod1() && collab2.intentionRevealingMethod2()) {
    return null;
    }

    if (collab3.intentionRevealingMethod3()) {
    throw new BusinessException();
    }
    // doSomething()
    return new EntityZ;
    }
    }

    Cette réflexion autour des responsabilités des objets permet d’enrichir notre domain model et aucun framework de ne le fera pour nous (cf http://weblogs.asp.net/jamauss/archive/2008/07/17/how-to-determine-object-responsibility.aspx).

    Pour atteindre ce niveau de coding et l’appliquer systématiquement il faut beaucoup d’expérience (skilled developpers comme le dit Martin Fowler), connaitre des patterns de refactoring (on ne fait pas un domain model optimal du 1er coup) à coupler avec des tests unitaires, une bonne connaissance des principes OO (lire les principes de Robert C Martin, de Martin Fowler, de Rod Johnson, etc), des connaissances de certains designs patterns et des frameworks pour les tâches techniques (spring, hibernate).

    Il n’existe pas de façon parfaite de coder, seulement des façons appropriées selon des contraintes définies qui constituent le contexte du projet.
    On peut juste faire de notre mieux si on aime faire les choses bien.
    Pour moi le DDD c’est l’élégance suprême! Bravo à Eric Evans et à ceux qui y arrivent.
    Moi j’essaie tous les jours et je n’obtiens pas leur pourcentage de réussite …
    Je reste pourtant persuadé des bienfaits d’une telle pratique.

    Encore bravo d’avoir initié une telle discussion!
    En tant que fervent adepte du DDD, je t’encourage à poursuivre.

    Cordialement,
    Louis, fervent adepte de l’objet, du DDD et du TDD.

  7. Publié par Rénald VENANT-VALERY, Il y a 1 mois

    Qu’entendez-vous par « la réutilisabilité » ?. Rendre le code fonctionnel réutilisable n’est pas une priorité en DDD, mais il s’agit peut-être au contraire d’un code-smell de conception. L’objectif du Bounded Context est d’encapsuler un maximum de choses dans ses modèles, et de sanctuariser le métier. Le Ubiquitous Language vient consolider cela. L’utilisation de notifications permet aussi aux applications de ne pas avoir à « se connaître » entre elles.

    Le DDD prône l’écriture d’un code spécifique, jusque dans la façon de nommer les diverses entités de la solution, en respect du langage omniprésent qui revêt une valeur « contractuelle ». Il est préférable que le code soit donc le plus expressif possible. S’il est spécifique, aucun développeur ne prendra la responsabilité de le détourner de ses intentions d’origine. Le DDD insiste beaucoup plus sur les spécificités que sur d’éventuelles pistes de convergence ou de réutilisabilité. Cela permet de garantir un minimum de couplage entre certaines fonctionnalités, d’éloigner la possibilité d’un monolithe distribué, et de maintenir des ilôts applicatifs sains.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *