« Command Query Responsibility Segregation » et « bounded contexts ».

Julien on jan 17th 2010

Je sors de mon sommeil pour aborder une question posée sur la mailing list française d'Alt.net qui me tient à coeur. Pour paraphraser, nous avons le cas d'un client qui devient privilégié sur un site de e-commerce, ce qui lui donne droit à une livraison expresse pour toutes ses commandes en cours. L'auteur de la question souhaite comprendre comment est réparti la logique (mise à jour du client / passage des commandes en cours à une livraison expresse) et pourquoi Udi Dahan considère que l'utilisation d'un modèle objet pour représenter le domaine est un détail d'implémentation dans le cadre d'une approche CQRS.

Voici mon interprétation après avoir assisté à la formation d'Udi sur le SOA :

Commençons par la répartition de la logique :

Dans cet exemple, notre commande "MakeCustomerPreferred" sera exécuté dans un bounded context (entendez "service") différent de celui qui gère les ventes en cours. "MakeCustomerPreferred" semble par exemple rattaché à un service de CRM ou de marketing. En conséquence, cette commande ne peut pas mettre à jour directement une entité du bounded context "ventes". Ce n'est pas sa responsabilité (pensez "loose coupling" !) et ce ne serait pas scalable. Une fois que "MakeCustomerPreferred" aura été exécuté, le message handler (l'unité qui va traiter une commande ou un évènement donné) pourra lever un évènement du type "CustomerBecamePreferred". Ce dernier pourra lui même être écouté par un autre bounded context, comme celui des ventes, qui pourra à son tours décider de mettre à jour son sous système en conséquence.

En ce qui concerne l'utilisation d'un modèle objet du domaine :

Quand on applique cette approche architecturale de façon globale, le choix d'utiliser un modèle objet ou une approche "transaction script" devient du cas par cas. Chaque message handler  étant indépendant, on est libre de choisir le meilleur outil pour chaque cas d'utilisation. Par exemple, si on ne fait que mettre à jour un champ d'une table : pas besoin d'ORM ! On pourrait tout à fait imaginer n'exécuter qu'une simple requête SQL de type UPDATE. Au contraire, si l'exécution d'une logique complexe fait parti du processus de mise à jour, alors il se peut qu'un modèle objet soit plus adéquat. (Et d'ailleurs, qui à dit que SQL était le système de persistance le plus adapté à notre cas d'utilisation? Tout dépend !)

Filed in Command Query Responsibility Segregation, Domain Driven Design | 5 responses so far

5 Responses to “« Command Query Responsibility Segregation » et « bounded contexts ».”

  1. thinkbeforecoding jan 17th 2010 at 07:11 1

    Effectivement l’approche CQRS offre beaucoup d’avantages.
    Le déploiement des differents services peut être fait indépendement. Le context ‘marketing’ peut changer sans devoir toucher au context ‘ventes’.
    Il faut bien prendre garde cependant de bien distinguer les commandes et les evenements pour ne pas perdre les benefices du découplage : une commande provoque une modification et génère un (ou plusieurs evenements). Par contre un event handler ne doit pas faire de modification, il doit appeler une commande. Faire un raccourci réduit la flexibilité du système…

  2. Nieve jan 17th 2010 at 10:34 2

    Salut Julien,
    Bon, tout d’abord je doit dire que cette architecture est l’une de plus élégants solutions que j’ai vue jusqu’au aujourd’hui :)

    Puis, cette poste est tout à fait une excellente réponse à ma question; mais (évidemment) elle lève une autre question, une de manière plus générale: si on travaille au cas par cas, et on peut se trouver avec des différents manières à persister dans la base les changement, que deviendra l’homogénéité de la persistance? La maintenance, ne sera t elle affaiblie par telles différences / inconsistances??

  3. Julien jan 18th 2010 at 08:13 3

    Nieve : voici une bonne raison de faire mon second billet de l’année 2010, stay tunned !

  4. thinkbeforecoding jan 18th 2010 at 02:13 4

    @Nieve, bien entendu, tu n’as pas forcement interret à utiliser un type différent de persistence dans chacun de tes contextes, mais si les besoins spécifiques d’un contexte le demande, tu peux utiliser un type de persistence different.

    De toute façon, l’intégration des différents contextes se fait par les messages et non par une base de donnée. Un contexte ne doit jamais acceder aux données d’un autre contexte directement.

  5. « Bounded contexts » et persistance | The .Net frog nov 29th 2010 at 10:12 5

    [...] mon billet précédant, je faisais remarquer que la persistance pouvait être implémentée de différente façon au sein [...]

Trackback URI | Comments RSS

Leave a reply