<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Donkey Blog : DDD, CQRS, Event Sourcing, en Python]]></title><description><![CDATA[Retour d'expérience sur le Domain Driven Design, exemple d'utilisation des patterns stratégiques et tactiques, exemples d'architectures logicielles en Python]]></description><link>http://donkeyblog.fr/</link><image><url>http://donkeyblog.fr/favicon.png</url><title>Donkey Blog : DDD, CQRS, Event Sourcing, en Python</title><link>http://donkeyblog.fr/</link></image><generator>Ghost 5.37</generator><lastBuildDate>Wed, 06 May 2026 10:02:08 GMT</lastBuildDate><atom:link href="http://donkeyblog.fr/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Scrum, je t’ai aimé, mais je te quitte]]></title><description><![CDATA[<p><br></p><p>Il y a peu de temps je mettais en doute l&#x2019;efficacit&#xE9; de scrum, sur linkedIn, ici.</p><p>Crime de l&#xE8;se majest&#xE9; pour beaucoup !</p><p>J&#x2019;ai donc repens&#xE9; a tout &#xE7;a, et j&#x2019;ai essay&#xE9; de rassembler les d&#xE9;rives</p>]]></description><link>http://donkeyblog.fr/scrum-je-tai-aime-mais-je-te-quitte/</link><guid isPermaLink="false">67f810ceab6d3b005c3c69fd</guid><dc:creator><![CDATA[Bagouze]]></dc:creator><pubDate>Thu, 10 Apr 2025 18:48:25 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1549937917-03ccda498729?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fHZveWFnZXxlbnwwfHx8fDE3NDQzMTA1MDV8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1549937917-03ccda498729?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fHZveWFnZXxlbnwwfHx8fDE3NDQzMTA1MDV8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Scrum, je t&#x2019;ai aim&#xE9;, mais je te quitte"><p><br></p><p>Il y a peu de temps je mettais en doute l&#x2019;efficacit&#xE9; de scrum, sur linkedIn, ici.</p><p>Crime de l&#xE8;se majest&#xE9; pour beaucoup !</p><p>J&#x2019;ai donc repens&#xE9; a tout &#xE7;a, et j&#x2019;ai essay&#xE9; de rassembler les d&#xE9;rives souvent constat&#xE9;es dans les &#xE9;quipes scrum.</p><p>Ca fait tr&#xE8;s longtemps que je participe &#xE0; des &#xE9;quipes scrum, en tant que lead dev, &#xE9;quipier, scrum master, ou PO selon les besoins des clients.</p><p>Et les constats de dysfonctionnement que j&#x2019;ai pu faire sont souvent les m&#xEA;mes: </p><ol><li><strong>Les estimations. </strong><br>Scrum utilise largement les estimations.<br>Or celle ci ne servent strictement &#xE0; rien. Quelle que soit la m&#xE9;thode, tailles de tee-shirt, story point et consort, au bout d&#x2019;un moment les Tickets ( car souvent ce sont des ticket et non des User Story ) finissent par avoir tous peu ou prou la m&#xEA;me granularit&#xE9;, &#xE0; une vache pr&#xE8;s. D&#xE8;s lors passer du temps &#xE0; savoir si une story vaut 3 ou 5 points est une pure perte de temps. Ah et souvent par magie, les estimations sont transform&#xE9;es en deadline par simple application d&#x2019;une r&#xE8;gle de trois, tr&#xE8;s sympa quand il faut expliquer en permanence pourquoi tout ne s&#x2019;est pas d&#xE9;roul&#xE9; comme dans le plan.</li><li><strong>Les sprints sont trop charg&#xE9;s.</strong><br>M&#xEA;me si on estime avec application. M&#xEA;me si on fait en sorte de moins charger le sprint ( coucou la loi de Hofstadter ). En cons&#xE9;quence les fonctions livr&#xE9;es sont tr&#xE8;s souvent incompl&#xE8;tes. Normal, on commence tout pour faire plaisir aux parties prenantes, car on est humain, on veut bien faire, mais on finit jamais rien.<br></li><li><strong>Les objectifs sont absents. </strong><br>Les objectifs m&#xE9;tier du sprint sont au mieux flous, ou d&#xE9;finis a rebours mais souvent inexistants. <br>Normal, sauf coup de bol, le timing du sprint est la plupart du temps incompatible avec la r&#xE9;alisation d&#x2019;une fonction de bout en bout. C&#x2019;est soit trop court soit trop long, car fixe.<br></li><li><strong>Le cadre est trop fixe. </strong><br>On fixe &#xE0; l&#x2019;avance et &#xE0; intervalle r&#xE9;gulier les r&#xE9;unions de refinement / grooming / chiffrage de user story. <br>Et comme les PO vont plus vite &#xE0; comprendre, que les devs &#xE0; coder, on fait du stock de User story. &#xA0;Quoi de plus normal. Les backlogs deviennent ainsi un gros bordel. Il est souvent impossible de s&#x2019;y retrouver et le taux de story non r&#xE9;alis&#xE9;es ne fait qu&#x2019;augmenter. Saviez-vous que dans le lean &#xAB; toyotesque &#xBB; original, un stock &#xE9;tait valoris&#xE9; au passif d&#x2019;une entreprise et non &#xE0; l&#x2019;actif ? Dit autrement un stock co&#xFB;te du pognon, et ne rapporte rien. Et votre stock de User Story va vous co&#xFB;ter cher, m&#xEA;me si on ne s&#x2019;en rend pas bien compte.<br></li><li><strong>La pression monte. </strong><br>Comme le pain s&#x2019;accumule sur la planche, Les devs sont de plus en plus sous pressions &#xAB; viiiiite il faut avancer, les story s&#x2019;accumulent !! &#xBB; et le sprint a tendance &#xE0; porter de mieux en mieux son nom, car il faut &#xE9;couler le stock d&#x2019;US. Bye bye les t&#xE2;ches d&#x2019;am&#xE9;lioration de fond. Ah et n&#x2019;essayez pas de &#xAB; r&#xE9;server de la bande passante &#xBB; car, les sprints sont trop charg&#xE9;s, on vous le r&#xE9;p&#xE8;te, et une urgence quelconque aura t&#xF4;t fait de pr&#xE9;empter la pr&#xE9;cieuse bande passante, f&#xFB;t-elle imaginaire.<br></li><li><strong>Le stock de User Story. </strong><br>Les story sont &#xE9;crites et parfois chiffr&#xE9;es parfois longtemps avant d&#x2019;&#xEA;tre r&#xE9;alis&#xE9;es. Ainsi, au moment de s&#x2019;y mettre le dev a perdu la moiti&#xE9; du sch&#xE9;ma mental du besoin. Si tant est qu&#x2019;il ai r&#xE9;ussi &#xE0; s&#x2019;en faire un au moment du grooming. Cette compr&#xE9;hension m&#xE9;tier, est pourtant essentielle &#xE0; la r&#xE9;alisation de sa t&#xE2;che, afin de prendre les d&#xE9;cisions pertinentes, quand lors de la r&#xE9;alisation, il d&#xE9;couvrira les cas non-sp&#xE9;cifi&#xE9;s. Il y en a toujours. Le stock d&#x2019;US a un peu moisi, tout le monde a un peu perdu son temps.<br></li><li><strong>Les devs deviennent des machines. </strong><br>Cons&#xE9;quence plus ou moins directe des points 4 et 5, les devs manquent cruellement d&#x2019;ownership. Transform&#xE9;s en robot stakhanovistes par une m&#xE9;thode qu&#x2019;on leur ressasse comme miraculeuse mais qui ne peut que les mettre sous pression. J&#x2019;en ai m&#xEA;me vu refuser des tickets si TOUT n&#x2019;&#xE9;tait pas &#xE9;cris, jusqu&#x2019;aux structures de donn&#xE9;es &#xE0; tester. Apr&#xE8;s quand vous &#xEA;tes infantilis&#xE9;s au point de devoir demander l&#x2019;autorisation d&#x2019;am&#xE9;liorer la qualit&#xE9; logicielle, et que le PO refuse, car il y a plus urgent, ben vous pouvez commencer &#xE0; vous demander quelle est votre plus value.<br></li><li><strong>&quot;C&apos;est pas toi le PO ?&quot; </strong><br>Le r&#xF4;le de PO, parlons en tiens. Je n&#x2019;ai JAMAIS vu de PO. Je dis bien jamais. C&#x2019;est &#xE0; dire quelqu&#x2019;un qui collecte du feedback utilisateur, et qui oriente le produit en fonction. Je n&#x2019;ai certainement pas eu de chance. J&#x2019;ai en revanche souvent vu des gens d&#xE9;cliner les roadmap manag&#xE9;riales, dont moi hein, en rajoutant des petit plus &#xAB; ce qu&#x2019;il serait bien de faire &#xBB;. On fait donc au mieux, avec plus ou moins de r&#xE9;ussite. Bah, c&#x2019;est notre job &#xE0; plein temps, alors on occupe l&#x2019;espace, en empilant de la feature, dont l&#x2019;impact est variable. Mais bon on est pay&#xE9; pour &#xE7;a 40h semaine, alors on fait et&#x2026; zou Go To point 3.<br></li><li><strong>Les epics n&apos;en sont pas vraiment, et rien n&apos;avance. </strong><br>Cons&#xE9;quence de tout &#xE7;a les epics ne sont plus des epics, mais un genre de th&#xE8;me qui sert plus ou moins &#xE0; essayer de classer les story, pour voir si avec une bonne requ&#xEA;te multi crit&#xE8;re, on pourrait avoir une id&#xE9;e de quand est-ce que le produit sera fini. Aucune epic ne sera jamais termin&#xE9;e, on ne se choquera plus vraiment 200 epics en cours dans le backlog. Et le produit sera termin&#xE9;, bah, un jour.<br></li><li><strong>On perd notre temps au final. </strong><br>Et enfin, la m&#xE9;thode est assez lourde et consommatrice de temps. Ce qui fait d&#x2019;ailleurs souvent lever un sourcil d&#xE9;sapprobateur au management. Pour des refinement qui servent &#xE0; faire du stock, des d&#xE9;mos de fonction &#xE0; moiti&#xE9; faites o&#xF9; tout le monde dort, des r&#xE9;tro qui servent &#xE0; remonter qu&#x2019;il n&#x2019;y a plus de papier toilettes, parce que les 14 r&#xE9;tro pr&#xE9;c&#xE9;dentes n&#x2019;ont pas &#xE9;t&#xE9; suivies d&#x2019;actions concr&#xE8;tes. Et puis on a pas que &#xE7;a a faire, on 43 tickets &#xE0; livrer pour apr&#xE8;s demain.</li></ol><p>C&#x2019;est un peu tout &#xE7;a que je reproche &#xE0; scrum, car tout &#xE7;a arrive m&#xEA;me en &#xE9;tant compl&#xE8;tement conforme &#xE0; la m&#xE9;thode.</p><p>Alors on pourra me r&#xE9;pondre &#xAB; &#xA0;non mais tu appliques pas bien la m&#xE9;thode &#xBB;<br>Et c&#x2019;est tr&#xE8;s possible, j&#x2019;assume tout &#xE0; fait ne pas &#xEA;tre scrum-certified. Mais encore une fois, dans ces 10 points, j&#x2019;en ai vu la plupart revenir tr&#xE8;s souvent. Le hasard &#xE0; bon dos, mais quand m&#xEA;me.<br></p><p>Je commence s&#xE9;rieusement &#xE0; penser que ces d&#xE9;fauts sont inh&#xE9;rents, sinon &#xE0; la m&#xE9;thode, au moins a la possibilit&#xE9; de l&#x2019;appliquer au sein d&#x2019;une organisation plus vaste.</p><p>Quand la m&#xE9;thode ne fonctionne pas bien, premier r&#xE9;flexe: plus de m&#xE9;thode !<br>Plus de r&#xE9;unions, plus de rigueur, contraindre les chiffrages, refuser ci ou &#xE7;a&#x2026;. bref, s&#x2019;arc-bouter en d&#xE9;fense. &#xC7;a ne marche pas et isole encore plus les devs du reste du monde, pour booster la scro-sainte productivit&#xE9;. Isoler les devs est &#xE0; mon sens ce qui peut arriver de pire &#xE0; votre produit.</p><p>Bref, Scrum, je t&#x2019;ai aim&#xE9;, mais je te quitte. <br>J&#x2019;ai trouv&#xE9; mon nouvel amour. <br><br>Kanban. <br><br>Mais ceci est une autre histoire.</p>]]></content:encoded></item><item><title><![CDATA[#9 - Une architecture CQRS en python: Schéma Général]]></title><description><![CDATA[<h3 id="command-query-event-bus-dispatchers-handler-responseet-laddition">Command, Query, Event, Bus, Dispatchers, Handler, Response...<br>et l&apos;addition.<br></h3><p>L&apos;architecture que nous avons mis en place a &#xE9;t&#xE9; largement inspir&#xE9;e par un talk <a href="https://www.lilobase.me/?ref=donkey-blog-ddd-cqrs-event-sourcing-en-python">d&apos;Arnaud Lemaire</a>, <a href="https://afup.org/talks/2628-cqrs-fonctionnel-event-sourcing-domain-driven-design?ref=donkey-blog-ddd-cqrs-event-sourcing-en-python">que vous trouverez ici</a></p><p>Le gars va &#xE0; fond la caisse dans sa conf et</p>]]></description><link>http://donkeyblog.fr/python-cqrs-overview/</link><guid isPermaLink="false">6418d04f468b95005ba57f49</guid><category><![CDATA[Dev]]></category><category><![CDATA[python]]></category><dc:creator><![CDATA[Bagouze]]></dc:creator><pubDate>Tue, 26 Sep 2023 08:35:41 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1597424216910-9e56f8a09b8e?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fGNvbXBvbmVudHxlbnwwfHx8fDE2NzkzNDc5MDc&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<h3 id="command-query-event-bus-dispatchers-handler-responseet-laddition">Command, Query, Event, Bus, Dispatchers, Handler, Response...<br>et l&apos;addition.<br></h3><img src="https://images.unsplash.com/photo-1597424216910-9e56f8a09b8e?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fGNvbXBvbmVudHxlbnwwfHx8fDE2NzkzNDc5MDc&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="#9 - Une architecture CQRS en python: Sch&#xE9;ma G&#xE9;n&#xE9;ral"><p>L&apos;architecture que nous avons mis en place a &#xE9;t&#xE9; largement inspir&#xE9;e par un talk <a href="https://www.lilobase.me/?ref=donkey-blog-ddd-cqrs-event-sourcing-en-python">d&apos;Arnaud Lemaire</a>, <a href="https://afup.org/talks/2628-cqrs-fonctionnel-event-sourcing-domain-driven-design?ref=donkey-blog-ddd-cqrs-event-sourcing-en-python">que vous trouverez ici</a></p><p>Le gars va &#xE0; fond la caisse dans sa conf et pr&#xE9;sente un nombre de concept assez hallucinant en 45 minutes, il est d&apos;ailleurs impossible de tout comprendre au premier visionnage. </p><p>J&apos;ai donc un peu ponc&#xE9; le machin, et j&apos;ai fais une impl&#xE9;mentation &#xE0; partir de rien, en python, donc, afin de comprendre comment le tout se mettait en musique, l&apos;occasion de repartager tout &#xE7;a.</p><p>Avant de rentrer dans le d&#xE9;tail de chaque composant, un grand merci &#xE0; <a href="https://www.lilobase.me/?ref=donkey-blog-ddd-cqrs-event-sourcing-en-python">Arnaud</a> donc, qui gr&#xE2;ce a cette conf&#xE9;rence ultra dense, nous a permis de nous lancer dans la bonne direction en posant les bases de notre architecture CQRS. &#xA0;</p><h2 id="objectifs">Objectifs</h2><p>Les objectif classiques d&apos;une architecture CQRS, sont les suivants: </p><ul><li>S&#xE9;paration entre lectures et commandes</li><li>la mise en place de Cache pour les lectures </li><li>la mise en place de projection de data pour anticiper les productions de donn&#xE9;es</li><li>la possibilit&#xE9; de migrer vers de l&apos;event sourcing </li></ul><p>Par ailleurs le fait de lister les commandes et le requ&#xEA;tes de notre syst&#xE8;me va &#xE9;galement nous permettre de quitter l&apos;orientation CRUD / ressources qui &#xA0;a tendance &#xE0; engluer les syst&#xE8;mes &#xA0;dans une complexit&#xE9; technique inutile. </p><h2 id="principe-de-fonctionnements-g%C3%A9n%C3%A9raux">Principe de fonctionnements g&#xE9;n&#xE9;raux<br></h2><p>Une <strong>commande</strong> va d&#xE9;clencher un traitement, pour changer l&apos;&#xE9;tat interne du syst&#xE8;me. R&#xE9;server un billet de train, est une commande par exemple. </p><p>Une <strong>Query</strong> va r&#xE9;cup&#xE9;rer de l&apos;information dans le syst&#xE8;me, par exemple, si on se trouve sur un site de voyage, lister les billets de train que l&apos;on a command&#xE9; dans les 6 derniers mois, est une query.</p><p>Un <strong>Event</strong> (&#xE9;v&#xE8;nement) est &#xE9;mis dans le syst&#xE8;me ou depuis l&apos;ext&#xE9;rieur pour avertir d&apos;un changement qui est arriv&#xE9;. </p><p>Chacun de ces objets va donc v&#xE9;hiculer une intention au sein de notre syst&#xE8;me, pour d&#xE9;clencher des changements d&apos;&#xE9;tat ou des r&#xE9;cup&#xE9;ration d&apos;info. </p><p>On peut donc maintenant assez facilement imaginer qu&apos;un point de terminaison API, va uniquement cr&#xE9;er une commande ou une query, pour que celle ci soit trait&#xE9;e par notre syst&#xE8;me. </p><h2 id="sch%C3%A9ma-de-fonctionnement-g%C3%A9n%C3%A9ral">Sch&#xE9;ma de fonctionnement g&#xE9;n&#xE9;ral</h2><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/09/image-2.png" class="kg-image" alt="#9 - Une architecture CQRS en python: Sch&#xE9;ma G&#xE9;n&#xE9;ral" loading="lazy" width="1317" height="478" srcset="http://donkeyblog.fr/content/images/size/w600/2023/09/image-2.png 600w, http://donkeyblog.fr/content/images/size/w1000/2023/09/image-2.png 1000w, http://donkeyblog.fr/content/images/2023/09/image-2.png 1317w" sizes="(min-width: 720px) 720px"></figure><p>Le sch&#xE9;ma est divis&#xE9; en 3 sections, Infra, Application et Domaine, correspondant peu ou prou &#xE0; de la clean architecture d&#xE9;j&#xE0; pr&#xE9;sent&#xE9; <a href="http://donkeyblog.fr/le-monolithe-micro-service-ready/">ici</a>.</p><p>Les requ&#xEA;tes web arrivent dans la couche de gestion des endpoints, les commandes ou query correspondantes sont envoy&#xE9;es dans le syst&#xE8;me via les BUS appropri&#xE9;s. </p><p>Les BUS de middleware permettent de r&#xE9;aliser tout un tas de traitement transverses comme du log, un pattern Unit Of Work, de l&apos;auth, du contr&#xF4;le d&apos;acc&#xE8;s ou m&#xEA;me du cache. </p><p>Apr&#xE8;s avoir travers&#xE9; le BUS la commande est g&#xE9;r&#xE9;e par un handler, qui va s&apos;appuyer sur la couche domaine pour d&#xE9;clencher les traitements m&#xE9;tier. </p><p>Le prochain article d&#xE9;taillera le fonctionnement technique de la couche API Endpoint, bas&#xE9; sur Fastapi dans notre cas. </p>]]></content:encoded></item><item><title><![CDATA[#8 - Ubiquitous Langage : définition et mise en place]]></title><description><![CDATA[<p></p><p>En relisant le <a href="https://www.amazon.fr/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=sr_1_1?keywords=domain+driven+design&amp;qid=1684310823&amp;sprefix=domain+driven+desi%2Caps%2C103&amp;sr=8-1&amp;ref=donkey-blog-ddd-cqrs-event-sourcing-en-python">blue book,</a> je me suis rendu compte d&apos;une erreur de ma part, enfin, plut&#xF4;t un oubli, pour &#xEA;tre pr&#xE9;cis. En effet je me suis rappel&#xE9; que les 3 piliers du Domain Driven Design sont : </p><ul><li><strong>l&apos;approche strat&#xE9;</strong></li></ul>]]></description><link>http://donkeyblog.fr/8-ubiquitous-langage-mise-en-place/</link><guid isPermaLink="false">64648b08554b9b005c618328</guid><category><![CDATA[DDD : Patterns stratégiques]]></category><category><![CDATA[métier]]></category><dc:creator><![CDATA[Bagouze]]></dc:creator><pubDate>Thu, 25 May 2023 13:59:19 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1555431189-0fabf2667795?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDN8fHdvcmR8ZW58MHx8fHwxNjg0MzI2OTI0fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1555431189-0fabf2667795?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDN8fHdvcmR8ZW58MHx8fHwxNjg0MzI2OTI0fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="#8 - Ubiquitous Langage : d&#xE9;finition et mise en place"><p></p><p>En relisant le <a href="https://www.amazon.fr/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=sr_1_1?keywords=domain+driven+design&amp;qid=1684310823&amp;sprefix=domain+driven+desi%2Caps%2C103&amp;sr=8-1&amp;ref=donkey-blog-ddd-cqrs-event-sourcing-en-python">blue book,</a> je me suis rendu compte d&apos;une erreur de ma part, enfin, plut&#xF4;t un oubli, pour &#xEA;tre pr&#xE9;cis. En effet je me suis rappel&#xE9; que les 3 piliers du Domain Driven Design sont : </p><ul><li><strong>l&apos;approche strat&#xE9;gique</strong><br>J&apos;ai commenc&#xE9; &#xE0; en parler dans les 6 premiers articles, l&#xE0; on est OK.</li><li><strong>l&apos;approche tactique</strong><br>&#xE7;&apos;est pr&#xE9;vu, dans les articles &#xE0; venir, on est OK aussi l&#xE0; dessus. </li><li><strong>L&apos;ubiquitous langage </strong><br>Ah. <br>L&#xE0; on y est pas du tout OK en fait, j&apos;ai carr&#xE9;ment zapp&#xE9; cette partie, pourtant ultra importante. &#xA0;</li></ul><p>L&apos;objectif est de d&#xE9;finir et de nommer, <strong>de mani&#xE8;re unique et non ambig&#xFC;e</strong>, les diff&#xE9;rents concepts et entit&#xE9;s de notre application, et surtout de faire en sorte que cete terminologie soit partag&#xE9;e entre toutes les parties prenante du projet. <br>Vous me direz, &quot;c&apos;est la base&quot;, et effectivement, &#xE7;a l&apos;est.</p><p>Ceci &#xE9;tant il n&apos;est pas rare, sur un projet de d&#xE9;veloppement logiciel, que chaque partie prenante nomme les concepts utilis&#xE9;s un peu dans son coin. Cela peut aboutir a des difficult&#xE9;s de compr&#xE9;hension, entre le m&#xE9;tier et la technique, voir m&#xEA;me &#xE0; la duplication de terme pour designer un concept, parfois jusque dans le code. Tr&#xE8;s sympa quand vous gal&#xE9;rez d&#xE9;j&#xE0; &#xE0; comprendre le m&#xE9;tier, que vous vous rendez compte que les fonctions get_x et get_y font en r&#xE9;alit&#xE9; la m&#xEA;me chose. </p><p>La d&#xE9;finition d&apos;un langage partag&#xE9;, c&apos;est donc l&apos;occasion de mettre en place un glossaire, objectif de cet article donc. <br>Je triche un peu car comme j&apos;ai d&#xE9;j&#xE0; d&#xE9;velopp&#xE9; une version de l&apos;application que l&apos;on se propose d&apos;&#xE9;crire, j&apos;ai d&#xE9;j&#xE0; l&apos;ensemble du vocabulaire en t&#xEA;te, mais allons y. </p><p><em>NB: les concepts sont nomm&#xE9;s en fran&#xE7;ais, mais le code est en anglais, nous retiendrons donc la traduction entre parenth&#xE8;se comme r&#xE9;f&#xE9;rence, ce qui peut donner lieu &#xE0; des &#xE9;changes en franglais tr&#xE8;s jean-claude-vandammien lors des r&#xE9;unions, comme dans tout projet de r&#xE9;alisation informatique.</em></p><p><strong>Equipe (<em>team</em>) : </strong><br>On va commencer doucement, avec un concept qui parle &#xE0; tout le monde. Un &#xE9;quipe c&apos;est un groupe de joueur. Jusque l&#xE0;, &#xE7;a bouscule pas un train de marchandise, on est d&apos;accord. <br>Une &#xE9;quipe poss&#xE8;de aussi de la tr&#xE9;sorerie, un encadrement, un nombre de relances, un facteur de popularit&#xE9;. <br>Une &#xE9;quipe est construite pour participer &#xE0; une <u><em>comp&#xE9;tition</em></u>, elle est coach&#xE9;e par un <u><em>coach</em></u>. Elle doit respecter des <u><em>r&#xE8;gles de cr&#xE9;ation</em></u>, et enfin elle est assembl&#xE9;e avec des <u><em>joueurs</em></u> dont le nombre et le profil sont d&#xE9;finis par un <u><em>roster</em></u>. </p><p>C&apos;est d&#xE9;j&#xE0; un poil plus tendu vous aurez not&#xE9;. Nous allons donc d&#xE9;finir tous les termes ci-dessus. </p><p><strong>Comp&#xE9;tition (<em>competition</em>)</strong><br>Une comp&#xE9;tition, c&apos;est un &#xE9;v&#xE8;nement plus ou moins ponctuel, qui va fournir un cadre de rencontre &#xE0; diff&#xE9;rentes &#xE9;quipes. Une comp&#xE9;tition est organis&#xE9;e par un club, elle est g&#xE9;r&#xE9;e par un ou plusieurs responsables. Une comp&#xE9;tition peut-&#xEA;tre une ligue ou un tournoi, la comp&#xE9;tition fixe les r&#xE8;gles de cr&#xE9;ation des &#xE9;quipes, le mode de calcul des points et des points bonus.</p><p><strong>Ligue (<em>league</em>)</strong><br>Une ligue est un type particulier de comp&#xE9;tition, qui se d&#xE9;roule sur une p&#xE9;riode de temps long, et qui se caract&#xE9;rise par une programmation des matchs. Celle-ci peut-&#xEA;tre de type : <br>- calendrier: toutes les rencontres sont pr&#xE9;vues &#xE0; l&apos;avance dans le cadre des semaines de rencontres<br>- &quot;open&quot; seules les dates de rencontre sont pr&#xE9;vues (ou m&#xEA;me pas dans certains cas) et les joueurs pr&#xE9;sent tirent au sort leur adversaire. </p><p><strong>Tournoi (<em>tournament</em>)</strong><br>Un tournoi est un type particulier de comp&#xE9;tition, qui se d&#xE9;roule sur quelques jours max, et dont les appariement sont d&#xE9;termin&#xE9;s au fil de l&apos;eau, en utilisant une m&#xE9;thode de type <a href="https://fr.wikipedia.org/wiki/Syst%C3%A8me_suisse?ref=donkey-blog-ddd-cqrs-event-sourcing-en-python#:~:text=Pour%20l&apos;appariement%20de%20la,dernier%20du%20premier%20groupe%20etc.">&quot;ronde suisse&quot;</a>. &#xA0;</p><p><strong>Coach (coach)</strong><br>Afin de ne pas confondre le joueur humain qui joue physiquement &#xE0; Bloodbowl et le joueur fictif au sein d&apos;une &#xE9;quipe, on d&#xE9;signe par coach, le joueur qui joue &#xE0; Bloodbowl, et par joueur le joueur en temps que membre d&apos;une &#xE9;quipe de bloodbowl. </p><p><strong>Roster (roster) </strong><br>Une roster contient la d&#xE9;finition d&apos;un type d&apos;&#xE9;quipe. Donc le roster d&#xE9;signe l&apos;ensemble des r&#xE8;gles, pour un type d&apos;&#xE9;quipe donn&#xE9;, dont:<br>- la liste et la limite en nombre des types de joueur disponibles pour ce type d&apos;&#xE9;quipe<br>- le prix des relances d&apos;&#xE9;quipes pour ce type d&apos;&#xE9;quipe<br>- le groupe de roster de ce type d&apos;&#xE9;quipe<br>- les champions (star players) qui sont susceptibles de jouer avec ce roster. </p><p>Tout &#xE7;a est un peu d&#xE9;taill&#xE9;. Donc en r&#xE9;sum&#xE9; nous retiendrons qu&apos;un roster, contient les r&#xE8;gles de r&#xE9;f&#xE9;rence, applicables &#xE0; la cr&#xE9;ation d&apos;une &#xE9;quipe, quelle que soit la comp&#xE9;tition dans laquelle l&apos;&#xE9;quipe va jouer.</p><p><strong>Groupe de classement / poule &#xA0;(<em>ranking group</em>)</strong><br>Une comp&#xE9;tition peut choisir de grouper les &#xE9;quipes au sein de poule, afin de s&#xE9;parer les classements en plusieurs groupes. Le classement d&apos;une &#xE9;quipe au sein d&apos;une competition s&apos;entend donc au sein d&apos;un groupe de classement. Les poules ne jouent que sur les classements, les &#xE9;quipes peuvent toutjours rencontrer toutes les autres &#xE9;quipes d&apos;une comp&#xE9;tition, ind&#xE9;pendamment des groupes de classement.</p><p><strong>R&#xE8;gles de cr&#xE9;ation (<em>creation rules</em>)</strong><br>Ces r&#xE8;gles d&#xE9;finissent comment construire son &#xE9;quipe. Il existe, dans le monde de bloodbowl, 26 types d&apos;&#xE9;quipes (roster). Le coach qui souhaite construire une &#xE9;quipe choisi une des 26 possibilit&#xE9;s d&apos;&#xE9;quipe, et en fonction</p><p><strong>Champion / Starplayer : </strong><br>Les champions sont des personnages sp&#xE9;ciaux qui peuvent int&#xE9;grer temporairement une &#xE9;quipe, en fonction de la diff&#xE9;rence de puissance des deux &#xE9;quipes (inducement), afin de r&#xE9;duire les &#xE9;carts. </p><p><strong>Inducement</strong> :<br>L&apos;inducement repr&#xE9;sente la diff&#xE9;rence de puissance entre deux &#xE9;quipes, calcul&#xE9;e par une grandeur num&#xE9;rique caract&#xE9;ristique de l&apos;&#xE9;quipe: la team value (team value). </p><p><strong>Joueur:</strong><br>Un joueur est un membre (fictif) d&apos;une &#xE9;quipe, il prendra donc part &#xE0; des matchs. Notion simple &#xE0; ne pas confondre avec le coach, qui repr&#xE9;sente le joueur qui joue ces matchs sur table.</p><p><strong>Niveau d&apos;exp&#xE9;rience :</strong><br>Le niveau d&apos;exp&#xE9;rience d&apos;un joueur repr&#xE9;sente le nombre d&apos;am&#xE9;liorations qui ont &#xE9;t&#xE9; achet&#xE9;es par ce joueur, via la d&#xE9;pense de SPP (star player points). Le nombre d&apos;am&#xE9;lioration et donc le niveau d&apos;exp&#xE9;rience sont au maximum &#xE9;gale &#xE0; 7.</p><p><strong>Points d&apos;exp&#xE9;rience / Star player points ou SPP : </strong><br>Les points d&apos;exp&#xE9;rience sont gagn&#xE9;s par les joueurs d&apos;une &#xE9;quipe, lorsqu&apos;ils r&#xE9;alisent certaines action au cours d&apos;un match. Les points d&apos;exp&#xE9;rience sont attribu&#xE9;s selon un bar&#xE8;me qui d&#xE9;pend des actions r&#xE9;alis&#xE9;es, et ce bar&#xE8;me doit pouvoir &#xEA;tre adapt&#xE9; au sein d&apos;une comp&#xE9;tition. Les comp&#xE9;tition de type tournoi ne rapportent pas de point d&apos;exp&#xE9;rience. Les points d&apos;exp&#xE9;riences sont accumul&#xE9;s par chaque joueur, puis d&#xE9;pens&#xE9;s pour acheter des augmentations. Cette logique se rapproche de la gestion d&apos;un compte en banque. </p><p><strong>Augmentation de joueur / player upgrade : </strong><br>L&apos;augmentation d&apos;un joueur vient modifier le profil statistique et / ou les comp&#xE9;tences de ce joueur, puis lui attribuer de nouvelles facult&#xE9;es. Les augmentations de joueurs peuvent &#xEA;tre gagn&#xE9;es par l&apos;acquisition de point de comp&#xE9;tences, ou affect&#xE9;es gratuitement par un commissaire de ligue, dans le cadre d&apos;une modification manuelle de joueur.</p><p><strong>Diminution de joueur / player Downgrade : </strong><br>Ce m&#xE9;canisme est l&apos;inverse du pr&#xE9;c&#xE9;dent, et refl&#xE8;te g&#xE9;n&#xE9;ralement le fait qu&apos;un joueur ait &#xE9;t&#xE9; bless&#xE9; au cours d&apos;un match. Le joueur en question va donc perdre certaines capacit&#xE9;s. Le profil de base du joueur, issue de la ligne de roster qui lui correspond, va donc &#xEA;tre modifi&#xE9; par le player downgrade. </p><p><strong>Customisation d&apos;&#xE9;quipe : </strong><br>La customisation d&apos;&#xE9;quipe permet de modifier manuellement, la tr&#xE9;sorerie, la popularit&#xE9;, ou les autres grandeurs caract&#xE9;ristiques d&apos;une &#xE9;quipe. Par modification manuelle, on d&#xE9;signe une modification d&apos;une &#xE9;quipe qui n&apos;est pas cr&#xE9;e suite &#xE0; un match. Cette fonction est g&#xE9;n&#xE9;ralement utilis&#xE9;e pour corriger &#xE0; post&#xE9;riori une erreur dans le rapport de match. </p><p><strong>Customisation de joueur : </strong><br>Le fait de customiser un joueur revient &#xE0; modifier sont profil, ses comp&#xE9;tences et ou son prix, sans affecter la ligne de roster correspondante. Cela est utile pour prendre en charge des r&#xE8;gles sp&#xE9;ciales qui pourraient intervenir lors de l&apos;ann&#xE9;e.</p><h2 id="conclusion">Conclusion</h2><p>J&apos;aurais pu continuer &#xE0; &#xE9;grener les termes m&#xE9;tiers, puisque nous avons, je pense, vu a peu pr&#xE8;s un tiers des notions. <br>N&#xE9;anmoins, les notions principales ont &#xE9;t&#xE9; d&#xE9;finies, et la valeur de cet article ne se situe pas n&#xE9;c&#xE9;ssairement sur la compl&#xE9;tude des informations qu&apos;il contient. <br>L&apos;objectif &#xE9;tait plut&#xF4;t de souligner l&apos;importance de s&apos;entendre sur les termes, les concepts et les r&#xE8;gles m&#xE9;tiers qui sont g&#xE9;n&#xE9;ralement encapsul&#xE9;es dans les termes eux m&#xEA;mes. <br>D&apos;ou l&apos;importance cruciale de se comprendre entre parties prenantes, et donc l&apos;importance de ce petit glossaire d&apos;exemple. </p><p></p><p> </p><p></p>]]></content:encoded></item><item><title><![CDATA[#7 - DDD Tactique: Le monolithe "micro-service ready"]]></title><description><![CDATA[<p><br>Encore un concept que j&apos;ai piqu&#xE9; aux anciens d&apos;Arpinum, JB Dusseault et Arnaud Lemaire. J&apos;esp&#xE8;re qu&apos;ils ne m&apos;en voudront pas trop :) D&apos;ailleurs je ne sais pas si ils sont eux m&#xEA;me les auteurs</p>]]></description><link>http://donkeyblog.fr/le-monolithe-micro-service-ready/</link><guid isPermaLink="false">641a2f4413a754005b79bdb1</guid><category><![CDATA[DDD : Patterns Tactiques]]></category><dc:creator><![CDATA[Bagouze]]></dc:creator><pubDate>Wed, 17 May 2023 07:55:15 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1563754672161-1da06ecad541?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDI2fHxjYWlsbG91fGVufDB8fHx8MTY3OTQzODM1Mw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1563754672161-1da06ecad541?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDI2fHxjYWlsbG91fGVufDB8fHx8MTY3OTQzODM1Mw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="#7 - DDD Tactique: Le monolithe &quot;micro-service ready&quot;"><p><br>Encore un concept que j&apos;ai piqu&#xE9; aux anciens d&apos;Arpinum, JB Dusseault et Arnaud Lemaire. J&apos;esp&#xE8;re qu&apos;ils ne m&apos;en voudront pas trop :) D&apos;ailleurs je ne sais pas si ils sont eux m&#xEA;me les auteurs de ce concept, Ils nous diront en commentaire, mais quoi qu&apos;il en soit c&apos;est gr&#xE2;ce &#xE0; eux que nous nous sommes familiaris&#xE9;s avec ce concept. Merci les gars !</p><h3 id="cest-quoi-un-monolithe-micro-service-ready-chef">C&apos;est quoi un monolithe micro-service ready, chef ?</h3><p><br>C&apos;est le canada-dry du micro-service. &#xC7;a en a le go&#xFB;t, &#xE7;a en a l&apos;odeur... mais &#xE7;a n&apos;en est pas. <br>En gros on garde un d&#xE9;coupage en module logique isol&#xE9;s (nos bounded contexts), mais au lieu de dispatcher ces modules sur des processus ou des machines s&#xE9;par&#xE9;s, on garde tout &#xE7;a au sein d&apos;une seule application, sur un seul processus. Voir un seul thread, si on est en python... oui bon on fait ce qu&apos;on peut. </p><p>Donc on fait &quot;comme si&quot; on avait des micro-services, d&apos;un point de vue de l&apos;architecture logique, mais on garde une architecture physique unique. &#xC7;a permet de b&#xE9;n&#xE9;ficier des avantages de la maintenabilit&#xE9; li&#xE9;e &#xE0; la mise en place d&apos;unit&#xE9; logique tr&#xE8;s d&#xE9;coup&#xE9;es, sans avoir &#xE0; se tarter de l&apos;asynchronisme, de la com&apos; r&#xE9;seau, de la tol&#xE9;rance aux pannes, de l&apos;orchestration, du kubernetes et tout un tas de joyeuset&#xE9; qui n&apos;apportent pas forc&#xE9;ment grand chose. <br>Ce n&apos;est jamais vraiment &#xE9;vident de savoir jusqu&apos;ou aller, en particulier sur ces sujets de gestion thread / processus. Doit-on utiliser des brokers de message pour communiquer entre nos bounded contexts ? doit on-s&#xE9;parer la configuration de la persistence pour chacun de nos contextes ? donc faire en sorte que chaque brique logicielle ait sa propre configuration de base de donn&#xE9;es... Ce faisant on se rapprochait beaucoup d&apos;une architecture micro-services, et la complexit&#xE9; obligatoire qui en r&#xE9;sultait nous a paru largement overkill dans un premier temps. </p><p>Temps qui peut d&apos;ailleurs durer, avant que votre application ait vraiment besoin de passer &#xE0; l&apos;&#xE9;chelle. Genre, jamais pour un bon 95% des appli B2B, &#xE0; mon avis.<br>Donc sch&#xE9;matiquement notre appli ressemble &#xE0; &#xE7;a : </p><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image-1.png" class="kg-image" alt="#7 - DDD Tactique: Le monolithe &quot;micro-service ready&quot;" loading="lazy" width="1079" height="728" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-1.png 600w, http://donkeyblog.fr/content/images/size/w1000/2023/03/image-1.png 1000w, http://donkeyblog.fr/content/images/2023/03/image-1.png 1079w" sizes="(min-width: 720px) 720px"></figure><p>Le contenu des blocs va &#xEA;tre calqu&#xE9; sur notre analyse strat&#xE9;gique, pour que chacun de nos blocs corresponde &#xE0; un Bounded Contexte tel que nous les avons d&#xE9;finis dans l&apos;article pr&#xE9;c&#xE9;dent. </p><h3 id="les-grand-principes">Les grand principes </h3><p><br>Ok, maintenant qu&apos;on a dit &#xE7;a, on est pas plus avanc&#xE9;. Donc lorsque l&apos;on a pens&#xE9; l&apos;architecture de notre syst&#xE8;me, nous avons utilis&#xE9; un ensemble de r&#xE8;gles simples pour nous aider &#xE0; d&#xE9;cider lorsque nous &#xE9;tions dans le flou : </p><ul><li><strong>Multiple briques</strong><br>L&apos;application sera compos&#xE9; de plusieurs bounded contexts, isol&#xE9;s les uns des autres. Chaque Bounded Context dans un r&#xE9;pertoire d&#xE9;di&#xE9;, mais surtout il est &#xE9;videmment interdit d&apos;importer ou de faire r&#xE9;f&#xE9;rence &#xE0; des objets externes depuis un bounded context donn&#xE9;. <br>En gros ce qu&apos;on veut &#xE9;viter ce sont des importations crado entre bounded context, qui viendraient coupler fortement nos contextes. C&apos;est tout con, mais dans presque tous les projets django que j&apos;ai crois&#xE9;, ce principe &#xA0;n&apos;&#xE9;tait pas du tout respect&#xE9;, entrainant des d&#xE9;pendances fortes entre les apps du projet.</li><li><strong>R&#xE9;utilisabilit&#xE9;</strong><br>Par cons&#xE9;quent, chaque bounded context doit dans l&apos;absolu pouvoir &#xEA;tre compl&#xE8;tement &quot;d&#xE9;croch&#xE9;&quot; de l&apos;application pour &#xEA;tre r&#xE9;utilis&#xE9; directement dans une autre application, si tant est que la nouvelle application fonctionne sur les m&#xEA;mes principes d&apos;infra que l&apos;appli initiale. Cela nous permet de trancher sur les limites d&apos;influence de tel ou tel contexte. Cela signifie aussi que chaque bounded context doit &#xEA;tre en mesure de g&#xE8;rer ses points d&apos;entr&#xE9;e. Donc la fourniture des endpoints d&apos;api, de mani&#xE8;re autonome et namespac&#xE9;.</li><li><strong>CQRS / CQRS-ES / CRUD</strong><br>Chaque Bounded Context sera potentiellement architectur&#xE9; selon des principes diff&#xE9;rents. Par d&#xE9;faut nous utiliserons une architecture CQRS, que nous d&#xE9;taillerons dans un futur article. <br>Nous opterons pour le CQRS + Event Sourcing, dans le cas ou la dimension temporelle du stockage apporte un plus. Les &#xE9;volutions de joueurs et d&apos;&#xE9;quipes seront un excellent cas d&apos;usage pour l&apos;Event Sourcing. Enfin le CRUD sera r&#xE9;serv&#xE9; aux contextes qui g&#xE8;re un stockage na&#xEF;f, genre le moteur de blog, embarqu&#xE9; dans le contexte communication. &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; </li><li><strong>Onion / Clean Architecture</strong><br>Chaque Bounded contexte est organis&#xE9; en interne en suivant les principes de l&apos;architecture en couche pour la gestion du m&#xE9;tier. L&apos;architecture en couche, ou clean architecture chez <a href="https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html?ref=donkey-blog-ddd-cqrs-event-sourcing-en-python">Uncle Bob.</a> Pour m&#xE9;moire une architecture en couche se d&#xE9;compose en 3,4 couches ( 3 chez nous ) et suit le sch&#xE9;ma th&#xE9;orique ci-dessous :</li></ul><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image.png" class="kg-image" alt="#7 - DDD Tactique: Le monolithe &quot;micro-service ready&quot;" loading="lazy" width="660" height="474" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image.png 600w, http://donkeyblog.fr/content/images/2023/03/image.png 660w"></figure><p>Nous avons donc organis&#xE9; notre code en trois couches : </p><ul><li>Infrastructure : <br>La couche de plus haut niveau, en charge &#xE0; la fois de la gestion des requ&#xEA;tes web entrante, de l&apos;int&#xE9;raction avec une ligne de commande, de la persistance des donn&#xE9;es et &#xE9;ventuellement de leur serialisation pour envoi sur le r&#xE9;seau.</li><li>Application : <br>C&apos;est dans cette couche que nos cas d&apos;utilisation doivent appara&#xEE;tre. Nous aurons par exemple un fichier start_user_signup.py dans cette couche. Nous verrons ensuite ce que nous mettons dans ce fichier. </li><li>Domain : <br>C&apos;est enfin ici que vient se loger tout le m&#xE9;tier de notre application. Le m&#xE9;tier est mod&#xE9;lis&#xE9; par une structure de classe et de m&#xE9;thodes python, qui n&apos;ont aucune d&#xE9;pendance avec quoi que ce soit d&apos;autre. Nous utilisons une r&#xE8;gle simple pour notre code m&#xE9;tier : Le product owner doit pouvoir lire le code et comprendre ce qui s&apos;y passe. C&apos;est cette r&#xE8;gle toute conne qui va nous guider dans l&apos;&#xE9;criture de notre m&#xE9;tier. C&apos;est cette r&#xE8;gle qui va permettre de nommer correctement nos entit&#xE9;s, nos aggr&#xE9;gats et nos value objects. Concepts sur lesquels nous reviendrons. </li></ul><p>De plus la r&#xE8;gle fondamentale d&apos;une architecture en couche est simple, une couche interne ne peux jamais d&#xE9;pendre d&apos;une couche de niveau sup&#xE9;rieure. Donc par exemple, la couche application ne peut jamais importer quoi que ce soit de la couche infrastructure. La couche Domain elle ne doit rien importer &#xE0; part les libs de base du langage. <br><br><strong>Ceci &#xE9;tant, en vrai, pour le moment on a pas besoin de tout &#xE7;a.</strong> C&apos;est un r&#xE9;flexe de partir en concevant une apli avec tout se bordel, mais on en a pas besoin, pour le moment. </p><p>Ce dont on a besoin c&apos;est de code qui tourne, et qui fait des choses. <br>On appelle &#xE7;a du code m&#xE9;tier. <br>Et le code m&#xE9;tier il va dans la couche domaine. <br>Donc.... ben on va commencer &#xE0; &#xE9;crire du code m&#xE9;tier. On verra plus tard ou est-ce qu&apos;il doit tourner, comment sont stocker ses &#xE9;tats et tout &#xE7;a. <br>pour le moment: on code. </p><h2></h2>]]></content:encoded></item><item><title><![CDATA[#6 - DDD Stratégique : les premiers Bounded Contexts]]></title><description><![CDATA[<p></p><p><em>Bounded Context is a central pattern in Domain-Driven Design. It is the focus of DDD&apos;s strategic design section which is all about dealing with large models and teams. DDD deals with large models by dividing them into different Bounded Contexts and being explicit about their interrelationships.</em><br>Martin Fowler.</p>]]></description><link>http://donkeyblog.fr/6-proposer-une-modelisation-mise-en-place-des-bounded-contexts/</link><guid isPermaLink="false">6421bd14554b9b005c618016</guid><category><![CDATA[DDD : Patterns stratégiques]]></category><dc:creator><![CDATA[Bagouze]]></dc:creator><pubDate>Tue, 02 May 2023 08:44:05 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1597372811123-d0f1795bbdf9?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fGJvdW5kYXJ5fGVufDB8fHx8MTY4MzAxNzExNQ&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1597372811123-d0f1795bbdf9?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fGJvdW5kYXJ5fGVufDB8fHx8MTY4MzAxNzExNQ&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="#6 - DDD Strat&#xE9;gique : les premiers Bounded Contexts"><p></p><p><em>Bounded Context is a central pattern in Domain-Driven Design. It is the focus of DDD&apos;s strategic design section which is all about dealing with large models and teams. DDD deals with large models by dividing them into different Bounded Contexts and being explicit about their interrelationships.</em><br>Martin Fowler. </p><h3 id="identifier-les-contextes-m%C3%A9tierbounded-contexts">Identifier les contextes m&#xE9;tier - bounded contexts</h3><p>Dans l&apos;article pr&#xE9;c&#xE9;dent, nous avons aboutit &#xE0; la cr&#xE9;ation d&apos;une cartographie des domaines m&#xE9;tier. <br></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://donkeyblog.fr/content/images/2023/03/image-19.png" class="kg-image" alt="#6 - DDD Strat&#xE9;gique : les premiers Bounded Contexts" loading="lazy" width="1042" height="610" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-19.png 600w, http://donkeyblog.fr/content/images/size/w1000/2023/03/image-19.png 1000w, http://donkeyblog.fr/content/images/2023/03/image-19.png 1042w" sizes="(min-width: 720px) 720px"><figcaption>Cartographie des domaines d&apos;une gestion de ligue de Boodbowl</figcaption></figure><p><br>Nous allons maintenant voir comment passer de cette mod&#xE9;lisation de domaine, &#xE0; une proposition de mod&#xE9;lisation d&apos;architecture logicielle. Donc en quelque sortes, comment passer de la mod&#xE9;lisation du probl&#xE8;me &#xE0; la mod&#xE9;lisation de la solution.</p><p>L&apos;identification de ces contextes m&#xE9;tier est issue du regroupement de processus &#xA0;li&#xE9;s entre eux. L&apos;architecture logicielle cible doit donc nous permettre de r&#xE9;pliquer cette organisation m&#xE9;tier, dans le code. Nous allons donc designer une architecture qui fait la part belle aux &quot;modules&quot; m&#xE9;tier. C&apos;est a dire &#xE0; des &quot;paquets&quot; fonctionnellement coh&#xE9;rent, et dont l&apos;action se borne &#xE0; un aspect du cycle de vie de nos processus. C&apos;est ce que le Domain Driven Design appelle le &quot;bounded context&quot; ou contexte d&apos;utilisation. </p><p>Et l&#xE0; en toute logique vous allez me dire, &quot;ouais ben super je fais un contexte &apos;&#xE9;quipe&apos; et je mets tout dedans&quot;. </p><p>Alors oui, </p><p>mais non. <br><br>D&#xE9;j&#xE0; cela ne sera pas super coh&#xE9;rent avec notre cartographie m&#xE9;tier, donc non. <br>Mais raisonnons par l&apos;absurde, et mettons que l&apos;on mod&#xE9;lise une &#xE9;quipe dans son enti&#xE8;ret&#xE9;, avec toutes ses responsabilit&#xE9;s, dans un seul module orient&#xE9; entit&#xE9;. Donc in fine, dans une seule bonne grosse classe. <br>Pensez-vous que nous allons avoir besoin de toutes les donn&#xE9;es de la classe tout le temps ?<br>Question con hein, mais pensez vous que la notion d&apos;&#xE9;quipe affich&#xE9;e dans un tableau de classement, soit la m&#xEA;me que la notion d&apos;&#xE9;quipe utilis&#xE9;e dans un rapport de match ? <br>Dans le premier cas vous allez avoir besoin du nom, du logo de l&apos;&#xE9;quipe, de son coach et des ses point de classement. <br>Dans le second cas, les points de classement ne vous servent &#xE0; rien, en revanche il vous la liste des joueurs, leur niveau d&apos;exp&#xE9;rience, savoir si ils ont &#xE9;t&#xE9; bless&#xE9;s si ils ont particip&#xE9; au match... <br>Donc ces deux &quot;facettes&quot; de la notion d&apos;&#xE9;quipe, n&apos;ont en r&#xE9;alit&#xE9; rien &#xE0; voir l&apos;une avec l&apos;autre, selon le contexte dans lequel on manipule la notion. Si on vient les lier dans l&apos;impl&#xE9;mentation, on va passer notre temps &#xE0; se trimballer des donn&#xE9;es, dont on ne sert que partiellement. Et &#xE7;a ralentit toute la machine, &#xE0; la fois en Run mais aussi en Build, car les structures deviennent trop volumineuse.<br>Il est donc n&#xE9;c&#xE9;ssaire de dissocier ces deux facettes, et de ranger chaque d&#xE9;claration a sa place, dans le r&#xE9;pertoire qui vient mod&#xE9;liser le contexte d&apos;ex&#xE9;cution: le fameux bounded contexte. <br><br>C&apos;est pas plus compliqu&#xE9; que &#xE7;a.<br><br>En revanche c&apos;est ultra contre intuitif et c&apos;est aussi un peu l&apos;inverse de ce que l&apos;on nous enseigne &#xE0; l&apos;&#xE9;cole : mod&#xE9;liser une entit&#xE9; avec toutes se responsabilit&#xE9;, pour surtout ne pas se r&#xE9;p&#xE9;ter, le fameux principe Don&apos;t Repeat Yourself - DRY. C&apos;est ce principe DRY &#xE0; qui il est obligatoire de dire au revoir, pour le bien de notre architecture, dans une certaine mesure. </p><p>Et d&apos;un coup d&apos;un seul deux ph&#xE9;nom&#xE8;nes vont appara&#xEE;tre : </p><ul><li>une simplification drastique &#xE0; l&apos;&#xE9;chelle locale</li><li>une complexification non moins drastique &#xE0; l&apos;&#xE9;chelle de l&apos;architecture de l&apos;application</li></ul><p>Mais nous verrons &#xE7;a quand nous seront dans le code, dans le prochain article, et nous aurons largement le temps d&apos;explorer plus en d&#xE9;tails la construction interne d&apos;un Bounded Context, en tant que composant logiciel de notre application.</p><h3 id="nos-bounded-contextes-et-lapproche-model-it-wrong">Nos bounded contextes, et l&apos;approche &quot;Model it wrong&quot;</h3><p>Cet article &#xE0; pris davantage de temps &#xE0; &#xE9;crire que les autres, pour plusieurs raisons, dont la principale est la peur de se tromper. </p><p>En effet j&apos;ai men&#xE9; une premi&#xE8;re analyse qui aboutit au sch&#xE9;ma ci-dessus, une premi&#xE8;re version de ce qu&apos;on appelle une contexte map, mais que se passe-t-il si les bounded context identifi&#xE9;s ne sont pas les bons ? il faudra n&#xE9;cessairement retoucher cette map, pour que tout soit bien propre dans l&apos;article, afin de ne pas passer pour un charlot. <br>Et quelle garantie ai-je &#xE0; ce stade que ma mod&#xE9;lisation est la bonne ? Carr&#xE9;ment aucune. </p><p>C&apos;est encore un point relativement paralysant dans l&apos;approche DDD. On n&apos;est pas s&#xFB;r de faire &quot;juste&quot;. <br>Ce que l&apos;on doit apprendre ici, c&apos;est que &quot;juste&quot; est en r&#xE9;alit&#xE9; une notion qui n&apos;existe pas en DDD. Il y a des mod&#xE9;lisations qui fonctionnent, et d&apos;autre qui fonctionnent moins bien, mais nous ne savons pas, au moment ou l&apos;on d&#xE9;marre un projet dans quel cas nous nous trouvons. Nous sommes donc bien avanc&#xE9;s !</p><p>Donc je ne sais pas si la mod&#xE9;lisation actuelle de la solution est pertinente, ou non. Et ce n&apos;est pas forc&#xE9;ment grave. </p><p>Ce qui compte c&apos;est de d&#xE9;marrer. Notre mod&#xE9;lisation est forc&#xE9;ment fausse, au moins dans une certaine mesure &#xE0; l&apos;&#xE9;tape ou nous en sommes. Nous avons juste employ&#xE9; des techniques de mod&#xE9;lisation du probl&#xE8;me qui nous permettent de ne pas faire trop faux, dans une premi&#xE8;re approche. </p><p>C&apos;est comme &#xE7;a que nous avons envisag&#xE9; la m&#xE9;thode &quot;Model It Wrong&quot;. </p><p>Nous jugerons de la pertinence de notre d&#xE9;coupage au fur et &#xE0; mesure de l&apos;impl&#xE9;mentation. Si nous sommes amen&#xE9; &#xE0; faire rentrer trop de responsabilit&#xE9;s dans un contexte, ou si certaines entit&#xE9;s deviennent p&#xE9;nible &#xE0; manipuler, c&apos;est le signe que notre granularit&#xE9; est trop importante, et qu&apos;une session de d&#xE9;coupage doit &#xEA;tre men&#xE9;e, afin sans doute de diviser un bounded context en deux.</p><h3 id="finalement-la-liste-des-bounded-contextes">Finalement la liste des bounded contextes </h3><p>Faire la liste compl&#xE8;te des bounded contexts, dont TOUTE l&apos;application aura besoin, &#xA0;va &#xEA;tre un exercice fastidieux et inutile &#xE0; ce stade (d&#xE9;j&#xE0; parce que nous ne savons pas bien quelles sont les fonctions m&#xE9;tier qui vont &#xEA;tre couverte in fine par notre appli).<br>Partons donc avec un premier objectif simple en t&#xEA;te. Cet objectif va nous permettre de rester dans un p&#xE9;rim&#xE8;tre raisonnable, et donc de poser l&apos;environnement technique de notre projet DDD. </p><p>Nous allons donc, dans un premier temps offrir &#xE0; nos utilisateurs de :</p><ul><li>Cr&#xE9;er un compte, v&#xE9;rifi&#xE9; par email pour acc&#xE9;der &#xE0; tout le contenu de la plateforme</li><li>Cr&#xE9;er une &#xE9;quipe </li><li>Inscrire cette &#xE9;quipe &#xE0; une ligue (qui aura &#xE9;t&#xE9; pr&#xE9;alablement cr&#xE9;e par un commissaire de ligue ) </li></ul><p>Pour pouvoir enchainer ces simples &#xE9;tapes, nous allons avoir besoin de la liste des contextes ci-dessous. </p><p><strong>Access: </strong><br>Le context qui va g&#xE9;rer les droits d&apos;acc&#xE8;s et de visualisation au sein de la plateforme. C&apos;est ce contexte qui va contenir les fonctions de login ou de cr&#xE9;ation de compte par exemple. Le domaine Onboarding va s&apos;appuyer sur les fonctions du contexte Access. Je ne suis pas compl&#xE8;tement s&#xFB;r du bien fond&#xE9; de la pr&#xE9;sence de ce contexte, un peu trop technique &#xE0; mon go&#xFB;t, mais partons avec et nous verrons bien si sa pr&#xE9;sence est n&#xE9;cessaire au fil de l&apos;eau. </p><p><strong>Communication : </strong><br>La fonction na&#xEF;ve est de pouvoir &#xE9;crire des articles sur la plateforme. On se doute d&#xE9;j&#xE0; que le m&#xE9;tier embarqu&#xE9; dans ce contexte va pas &#xEA;tre foufou. Nous allons plut&#xF4;t &#xEA;tre sur (comme disent les agents immobiliers) sur un contexte full CRUD. </p><p><strong>TeamRegistration :</strong><br>L&apos;objectif est ici de permettre aux futurs coach de cr&#xE9;er et d&apos;inscrire leurs &#xE9;quipes &#xE0; une saison, d&apos;une ligue, d&apos;un club. D&#xE9;j&#xE0; l&#xE0; il y a beaucoup plus de notions m&#xE9;tier. Et il n&apos;est pas du tout garantit que toutes ces notions m&#xE9;tiers doivent &#xEA;tres g&#xE9;r&#xE9;es au sein du contexe TeamRegistration. <br>- une &#xE9;quipe : cr&#xE9;er et inscrire une &#xE9;quipe semble le coeur de la fonctionnalit&#xE9; de ce domaine, donc ok, les entit&#xE9;s &quot;&#xE9;quipe&quot; et inscriptions devraient bien &#xEA;tre g&#xE9;r&#xE9;es ici<br>- un club / une ligue / une saison : Ces notions, simples &#xE0; appr&#xE9;hender, n&apos;ont &#xE0; priori aucunes raisons d&apos;&#xEA;tre g&#xE9;r&#xE9;es compl&#xE8;tement par le contexte team registration. Il para&#xEE;t plus juste que ces notions qui soient g&#xE9;r&#xE9;es par un contexte de cr&#xE9;ation / enregistrement de ligues et de clubs, d&#xE9;di&#xE9; &#xE0; cet objectif. Donc le domaine team and clubs devrait en quelque sorte s&apos;abonner aux &#xE9;v&#xE8;nements de gestion qui interviennent dans le domaines LeaguesAndClubRegistration. Un premier cas de communication entre bounded contexts sans doute. </p><p>Ceci &#xE9;tant, pour pouvoir cr&#xE9;er une team, nous allons &#xE9;galement devoir nous appuyer sur les r&#xE8;gles du jeu, pour cr&#xE9;er des &#xE9;quipes valides. Donc quelque part le contexte RuleRepository devra aussi nous envoyer des infos. </p><p><strong>LeaguesAndClubRegistration :</strong></p><p>Comme on en a besoin pour cr&#xE9;er une &#xE9;quipe, cr&#xE9;ons donc le contexte qui permet de g&#xE9;rer le cycle de vie des clubs, ligues, saison de comp&#xE9;tition. D&apos;ailleurs si on r&#xE9;fl&#xE9;chit cinq minutes, lorsque un de nous utilisateur va cr&#xE9;er une ligue, ne va-t-il pas avoir besoin de plus que clubs et ligue ? des r&#xE8;gles de d&#xE9;part par exemple, puis des r&#xE8;gles de calcul de classement, des d&#xE9;finitions de poule &#xE9;galement. <br>Doit on cr&#xE9;er un contexte pour ces entit&#xE9;s ? <br>Bonne question, et je ne suis pas s&#xFB;r qu&apos;il y ait de mauvaises r&#xE9;ponses &#xE0; cette question. Disons que oui, et nous verrons si ce choix est justifi&#xE9;. </p><p><strong>RankingRulesCreation : </strong></p><p>Ce domaine va nous permettre de cr&#xE9;er des r&#xE8;gles de calcul de classement. La mani&#xE8;re dont nous allons permettre &#xE0; l&apos;utilisateur de faire ses propres r&#xE8;gles ne sera &#xE0; mon avis pas triviale du tout. </p><p><strong>RulesRepository :</strong></p><p>La notion de r&#xE8;gles rejoint celle de r&#xE9;f&#xE9;rence. En tout cas dans le jeu qui nous concerne. Telle &#xE9;quipe peut avoir tel et tel joueur, en telle quantit&#xE9;... ce genre de chose. Sachant que nous avons environ 120 &#xE0; 150 profils de joueurs, r&#xE9;partis en environ 25 types d&apos;&#xE9;quipes diff&#xE9;rentes, pour vous donner une id&#xE9;e. </p><p>Ceci &#xE9;videmment sans compter les Star players, et les types d&apos;&#xE9;quipes (que l&apos;on appellera roster dans la suite) non-officiels, auquels viennent parfois s&apos;ajouter les roster et joueurs &quot;maisons&quot; c&apos;est a dire invent&#xE9;s par certains coachs, pour certaines ligues seulement. </p><p>Donc quand on parle de r&#xE8;gle, il s&apos;agit davantage de r&#xE9;f&#xE9;rentiel que de r&#xE8;gles m&#xE9;tier en tant que telle. </p><p><strong>Ouf !</strong></p><p>Bon normalement avec les contextes d&#xE9;finis ici, nous devrions &#xEA;tre en mesure de pouvoir remplir nos premiers objectifs m&#xE9;tier. C&apos;est &#xE0; dire que, logiquement, nous avons d&#xE9;finit les structures en charge de g&#xE9;rer les cylces de vie et les actions m&#xE9;tiers que nous allons appliquer sur nos premi&#xE8;res entit&#xE9;s. </p><p>En revanche, pour faire &#xE7;a, il va nous falloir poser TOUTE la tripaille technique. Il nous faut donc nous appuyer sur un cadre technique qui va supporter au mieux l&apos;expresssion du m&#xE9;tier identifi&#xE9;. </p><p>Les d&#xE9;veloppeurs vont donc trouver davantage leur compte dans la s&#xE9;rie d&apos;article qui suit: Le DDD Tactique - la mise en place de l&apos;architecture globale et particuli&#xE8;re. </p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[#5 - DDD Stratégique : Identifier les domaines et sous-domaines métier]]></title><description><![CDATA[<p></p><p>Si nous r&#xE9;sumons la d&#xE9;marche strat&#xE9;gique, nous avons jusqu&apos;&#xE0; pr&#xE9;sent : <br><a href="http://donkeyblog.fr/le-plan-dattaque/">#2: pos&#xE9; le plan de bataille</a><br><a href="http://donkeyblog.fr/strategie-identifier-les-acteurs/">#3: identifi&#xE9; les acteurs de notre domaine</a> <br><a href="http://donkeyblog.fr/4-ddd-strategique-modeliser-les-parcours-client/">#4: d&#xE9;cortiqu&#xE9; les processus m&#xE9;tiers de notre domaine</a><br><br>Nous allons</p>]]></description><link>http://donkeyblog.fr/5-identifier-les-domaines/</link><guid isPermaLink="false">641dc4e113a754005b79c09b</guid><dc:creator><![CDATA[Bagouze]]></dc:creator><pubDate>Tue, 28 Mar 2023 12:45:27 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1605693035432-d8b5c237e2a7?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fGJvdW5kYXJpZXN8ZW58MHx8fHwxNjc5OTMyNzI3&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1605693035432-d8b5c237e2a7?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fGJvdW5kYXJpZXN8ZW58MHx8fHwxNjc5OTMyNzI3&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="#5 - DDD Strat&#xE9;gique : Identifier les domaines et sous-domaines m&#xE9;tier"><p></p><p>Si nous r&#xE9;sumons la d&#xE9;marche strat&#xE9;gique, nous avons jusqu&apos;&#xE0; pr&#xE9;sent : <br><a href="http://donkeyblog.fr/le-plan-dattaque/">#2: pos&#xE9; le plan de bataille</a><br><a href="http://donkeyblog.fr/strategie-identifier-les-acteurs/">#3: identifi&#xE9; les acteurs de notre domaine</a> <br><a href="http://donkeyblog.fr/4-ddd-strategique-modeliser-les-parcours-client/">#4: d&#xE9;cortiqu&#xE9; les processus m&#xE9;tiers de notre domaine</a><br><br>Nous allons donc maintenant essayer de regrouper nos diff&#xE9;rent processus et sous-processus en sous-domaines m&#xE9;tier coh&#xE9;rents. Pour m&#xE9;moire, le domaine m&#xE9;tier auquel nous souhaitons nous adresser, est celui de la gestion d&apos;un club de jeu. Domaine qui en vaut un autre, et qui est assez facile &#xE0; se repr&#xE9;senter pour un lecteur occasionnel. </p><p><em>NB : &#xA0;Encore une fois, la d&#xE9;marche propos&#xE9; au fil de ces articles n&apos;a pas d&apos;autre valeur que celle d&apos;un retour d&apos;exp&#xE9;rience, ce n&apos;est ni un cours, ni une injonction &#xE0; suivre quoi que ce soit. Il s&apos;agit juste d&apos;expliquer comment nous nous y sommes pris pour adresser une probl&#xE9;matique Domain Driven Design, depuis le d&#xE9;but, jusqu&apos;&#xE0; la livraison. </em><br></p><h3 id="rappel-de-la-liste-des-processus">Rappel de la liste des processus</h3><p>Lors de l&apos;article pr&#xE9;c&#xE9;dent, nous avons donc utilis&#xE9; le <a href="https://www.google.fr/books/edition/Le_story_mapping/DxLPDwAAQBAJ?hl=fr&amp;gbpv=1&amp;printsec=frontcover&amp;ref=donkey-blog-ddd-cqrs-event-sourcing-en-python">story mapping</a>, pour arriver &#xE0; une d&#xE9;finition de processus, orient&#xE9;e acteurs, dont le r&#xE9;sultat est rappel&#xE9; ci-dessous : </p><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image-6.png" class="kg-image" alt="#5 - DDD Strat&#xE9;gique : Identifier les domaines et sous-domaines m&#xE9;tier" loading="lazy" width="855" height="734" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-6.png 600w, http://donkeyblog.fr/content/images/2023/03/image-6.png 855w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image-7.png" class="kg-image" alt="#5 - DDD Strat&#xE9;gique : Identifier les domaines et sous-domaines m&#xE9;tier" loading="lazy" width="718" height="519" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-7.png 600w, http://donkeyblog.fr/content/images/2023/03/image-7.png 718w"></figure><p>Il est donc l&apos;heure de dessiner des patato&#xEF;des afin de regrouper ensemble les cartes qui m&#xE9;ritent de l&apos;&#xEA;tre. </p><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image-8.png" class="kg-image" alt="#5 - DDD Strat&#xE9;gique : Identifier les domaines et sous-domaines m&#xE9;tier" loading="lazy" width="1318" height="634" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-8.png 600w, http://donkeyblog.fr/content/images/size/w1000/2023/03/image-8.png 1000w, http://donkeyblog.fr/content/images/2023/03/image-8.png 1318w" sizes="(min-width: 720px) 720px"></figure><p>Il est assez &#xE9;vident de faire un sous-domaine m&#xE9;tier regroupant l&apos;ensemble des fonctions de communication entre les parties. </p><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image-9.png" class="kg-image" alt="#5 - DDD Strat&#xE9;gique : Identifier les domaines et sous-domaines m&#xE9;tier" loading="lazy" width="972" height="514" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-9.png 600w, http://donkeyblog.fr/content/images/2023/03/image-9.png 972w" sizes="(min-width: 720px) 720px"></figure><p>Le processus de d&#xE9;finition initial semble int&#xE9;ressant a traiter isol&#xE9;ment, car c&apos;est ici que tout va d&#xE9;marrer, et c&apos;est &#xE9;galement ici, que des choix impactant le d&#xE9;roulement de nos processus ult&#xE9;rieur va se faire. </p><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image-11.png" class="kg-image" alt="#5 - DDD Strat&#xE9;gique : Identifier les domaines et sous-domaines m&#xE9;tier" loading="lazy" width="1417" height="736" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-11.png 600w, http://donkeyblog.fr/content/images/size/w1000/2023/03/image-11.png 1000w, http://donkeyblog.fr/content/images/2023/03/image-11.png 1417w" sizes="(min-width: 720px) 720px"></figure><p>L&apos;organisation au pr&#xE9;alable va sans doute &#xEA;tre li&#xE9;e, d&apos;une mani&#xE8;re ou d&apos;une autre au domaine pr&#xE9;c&#xE9;dent. </p><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image-12.png" class="kg-image" alt="#5 - DDD Strat&#xE9;gique : Identifier les domaines et sous-domaines m&#xE9;tier" loading="lazy" width="970" height="478" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-12.png 600w, http://donkeyblog.fr/content/images/2023/03/image-12.png 970w" sizes="(min-width: 720px) 720px"></figure><p>Cette activit&#xE9; commence &#xE0; approcher du coeur du r&#xE9;acteur de notre proposition : automatiser la gestion d&apos;une ligue. </p><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image-13.png" class="kg-image" alt="#5 - DDD Strat&#xE9;gique : Identifier les domaines et sous-domaines m&#xE9;tier" loading="lazy" width="1714" height="838" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-13.png 600w, http://donkeyblog.fr/content/images/size/w1000/2023/03/image-13.png 1000w, http://donkeyblog.fr/content/images/size/w1600/2023/03/image-13.png 1600w, http://donkeyblog.fr/content/images/2023/03/image-13.png 1714w" sizes="(min-width: 720px) 720px"></figure><p>Cette partie est la suite de la pr&#xE9;c&#xE9;dente. Il est d&apos;ailleurs l&#xE9;gitime de se poser la question de pourquoi nous avons choisi de la d&#xE9;tacher de la pr&#xE9;c&#xE9;dente. A priori le fait de consigner correctement les &#xE9;v&#xE8;nements de match, nous a sembl&#xE9; une &#xE9;tape et des enjeux diff&#xE9;rents de r&#xE9;aliser les calculs li&#xE9;s aux matchs en question. </p><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image-14.png" class="kg-image" alt="#5 - DDD Strat&#xE9;gique : Identifier les domaines et sous-domaines m&#xE9;tier" loading="lazy" width="1378" height="691" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-14.png 600w, http://donkeyblog.fr/content/images/size/w1000/2023/03/image-14.png 1000w, http://donkeyblog.fr/content/images/2023/03/image-14.png 1378w" sizes="(min-width: 720px) 720px"></figure><p>Il s&apos;agit ici de prendre en charge les impacts des calculs r&#xE9;alis&#xE9;s dans les rapport de matchs. L&apos;avenir dira si oui ou non la s&#xE9;paration &#xE9;tait n&#xE9;c&#xE9;ssaire.</p><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image-15.png" class="kg-image" alt="#5 - DDD Strat&#xE9;gique : Identifier les domaines et sous-domaines m&#xE9;tier" loading="lazy" width="916" height="437" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-15.png 600w, http://donkeyblog.fr/content/images/2023/03/image-15.png 916w" sizes="(min-width: 720px) 720px"></figure><p>La suite logique de la saisie d&apos;un match, c&apos;est l&apos;&#xE9;volution du classement, et l&apos;&#xE9;volution des &#xE9;quipes comme vu ci-dessous. </p><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image-16.png" class="kg-image" alt="#5 - DDD Strat&#xE9;gique : Identifier les domaines et sous-domaines m&#xE9;tier" loading="lazy" width="1046" height="496" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-16.png 600w, http://donkeyblog.fr/content/images/size/w1000/2023/03/image-16.png 1000w, http://donkeyblog.fr/content/images/2023/03/image-16.png 1046w" sizes="(min-width: 720px) 720px"></figure><p></p><p>L&apos;ensemble de ces domaines nous permet de construire la carte de sous-domaines ci-dessous : &#xA0;</p><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image-17.png" class="kg-image" alt="#5 - DDD Strat&#xE9;gique : Identifier les domaines et sous-domaines m&#xE9;tier" loading="lazy" width="1028" height="589" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-17.png 600w, http://donkeyblog.fr/content/images/size/w1000/2023/03/image-17.png 1000w, http://donkeyblog.fr/content/images/2023/03/image-17.png 1028w" sizes="(min-width: 720px) 720px"></figure><h3 id="generic-supporting-ou-core-subdomain">Generic, Supporting, ou Core Subdomain</h3><p>Chaque sous domaine n&apos;apporte pas la m&#xEA;me chose &#xE0; notre proposition de valeur. Ils n&apos;ont pas le m&#xEA;me outcome comme dirait Jean-Claude Van Damme. </p><p>Le domain Driven Design propose de classer ces domaines en trois grandes cat&#xE9;gories : </p><p><br><strong>- Generic :</strong> La commodit&#xE9;, ce par quoi nous devons passer pour faire fonctionner l&apos;ensemble mais qui est d&#xE9;j&#xE0; tellement r&#xE9;pandu que cela n&apos;apporte plus grand chose en terme de diff&#xE9;renciation. L&apos;exemple classique c&apos;est le syst&#xE8;me de paiement. Lorsque l&apos;on met en place un site ecommerce, il serait idiot de redevelopper depuis z&#xE9;ro un syst&#xE8;me de paiement. Et pourtant, sans syst&#xE8;me de paiement, le syst&#xE8;me ne fonctionne pas. Le paiement est donc un passage oblig&#xE9;, sans grande valeur ajout&#xE9;e. <br><br><strong>- Core : </strong>L&apos;autre bout du spectre, l&#xE0; on est dans le sp&#xE9;cifique m&#xE9;tier pur, les fonctions qui vont nous permettre d&apos;apporter une nouvelle proposition sur un march&#xE9;, l&#xE0; ou une techno r&#xE9;volutionnaire change la donne, bref,, le coeur du r&#xE9;acteur de notre proposition. C&apos;est &#xE9;videmment sur cette partie qu&apos;il faudra concentrer les effort de d&#xE9;veloppement, d&apos;UX, de tout en fait. Pour notre exemple c&apos;est la gestion des rapport de macth et les calculs associ&#xE9;s qui nous permettrons de changer la vie de nos utilisateurs. <br><br><strong>- Supporting : </strong><br>On est entre les deux. Pas compl&#xE8;tement de l&apos;ordre de la commodit&#xE9;, mais pas nous plus compl&#xE8;tement au centre de toutes les attentions. En g&#xE9;n&#xE9;ral classer les domaines selon les deux typologies pr&#xE9;c&#xE9;dentes est assez &#xE9;videntes, et pour ceux qui restent, il y a le supporting domain. La strat&#xE9;gie de r&#xE9;alisation des domaines du supporting mod&#xE8;les va &#xEA;tre assez variable selon les contextes. Pour notre exemple, les fonctions de communication pourraient &#xEA;tre consid&#xE9;r&#xE9;es comme du supporting, car elles sont nombreuses et au centre de pas mal d&apos;&#xE9;changes entre les coach et le commissaire de ligue, mais techniquement les moyens de communication sont plut&#xF4;t de l&apos;ordre de la commodit&#xE9;.<br></p><p>Si l&apos;on classe nos domaines selon les 3 cat&#xE9;gories ci dessus, on obtiendrait : </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://donkeyblog.fr/content/images/2023/03/image-18.png" class="kg-image" alt="#5 - DDD Strat&#xE9;gique : Identifier les domaines et sous-domaines m&#xE9;tier" loading="lazy" width="1059" height="626" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-18.png 600w, http://donkeyblog.fr/content/images/size/w1000/2023/03/image-18.png 1000w, http://donkeyblog.fr/content/images/2023/03/image-18.png 1059w" sizes="(min-width: 720px) 720px"><figcaption>bleu : Generic Subdomain / Vert : Supporting Subdomain / Jaune : Core subdomain</figcaption></figure><p>Maintenant qu&apos;une premi&#xE8;re mod&#xE9;lisation du domaine est pos&#xE9;e, nous allons voir comment proposer un d&#xE9;coupage fonctionnel qui permet de r&#xE9;pondre &#xE0; nos probl&#xE9;matiques, en appliquant une organisation aussi mirroir que possible, et en ajoutant peut-&#xEA;tre certaines pr&#xE9;occupation purement techniques. </p><p>La suite se trouve &#xE0; l&apos;article #6 L&apos;apparition des bounded contexts</p>]]></content:encoded></item><item><title><![CDATA[#4 - DDD Stratégique : Modéliser les parcours clients]]></title><description><![CDATA[Un exemple  d'utilisation du story mapping. Matérialiser les parcours clients d'une application, par l'exemple]]></description><link>http://donkeyblog.fr/4-ddd-strategique-modeliser-les-parcours-client/</link><guid isPermaLink="false">641db89013a754005b79c00f</guid><category><![CDATA[DDD : Patterns stratégiques]]></category><dc:creator><![CDATA[Bagouze]]></dc:creator><pubDate>Sat, 25 Mar 2023 08:39:52 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1679581858563-3c808d23f0fc?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8YWxsfDc3fHx8fHx8Mnx8MTY3OTczMzYzMQ&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1679581858563-3c808d23f0fc?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8YWxsfDc3fHx8fHx8Mnx8MTY3OTczMzYzMQ&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="#4 - DDD Strat&#xE9;gique : Mod&#xE9;liser les parcours clients"><p><br>L&apos;article 3 nous a permis de commencer &#xE0; nous familiariser avec le domaine, en d&#xE9;finissant les acteurs, et leurs besoins. L&apos;&#xE9;tape suivante pourrait &#xEA;tre de voir comment leur besoins prennent forme, &#xE0; l&apos;heure actuelle. Rentrer dans le d&#xE9;tail d&apos;un processus permet de mettre &#xE0; nu le dit processus, et donc d&apos;en comprendre tous les rouages. Et &#xE7;a c&apos;est top pour notre compr&#xE9;hension de ce qui se passe avant que l&apos;on commence &#xE0; intervenir, en sommes comment est organis&#xE9; le fameux probl&#xE8;me. <br></p><h2 id="d%C3%A9tailler-les-processus">D&#xE9;tailler les processus</h2><p>Pour rentrer dans ce niveau de d&#xE9;tail, il nous faut &#xE9;changer. Echanger cette fois ci de mani&#xE8;re un peu plus organis&#xE9;e, au travers d&apos;atelier de d&#xE9;finition. Il existe &#xE9;norm&#xE9;ment de fa&#xE7;ons d&apos;organiser un &#xE9;change pour mod&#xE9;liser un processus, des plus ou moins bonnes. Il y en a surtout une mauvaise. </p><p>La mauvaise c&apos;est<u> le cahier des charges.</u> </p><p>Un bon gros cahier des charges de 200 pages, qui d&#xE9;crit en d&#xE9;tail la couleur de fond du bouton de l&apos;&#xE9;cran 12, mais qui ne donne aucune compr&#xE9;hension &#xE9;tendue du domaine, et surtout un cahier des charges c&apos;est focalis&#xE9; vers la solution, pas sur le probl&#xE8;me. Le truc est donc aussi utile &#xE0; un dev qu&apos;un &#xA0;soutient-gorge &#xE0; une enclume.</p><p>Bref depuis quelques ann&#xE9;es et l&apos;apparition du design thinking, on voit appara&#xEE;tre des modes d&apos;&#xE9;change et d&apos;id&#xE9;ation bas&#xE9; sur des ateliers collaboratifs. Alors certes tout dans le design thinking n&apos;est pas a garder, mais certaines m&#xE9;thodes sont redoutablement efficace pour transmettre une vision. Les trois techniques d&apos;&#xE9;changes les plus &#xE0; la mode &#xE0; l&apos;heure actuelle sont list&#xE9;es ci-dessous. En revanche j&apos;avoue humblement ne pas &#xEA;tre un expert de l&apos;event storming, ou du domain story telling. Du story mapping, un peu plus d&#xE9;j&#xE0;. </p><p><strong>Le story mapping</strong><br>Cette technique fait un peu figure de doyenne, et existe depuis 2014 (c&apos;est quand m&#xEA;me incroyablement r&#xE9;cent...). Le bouquin de r&#xE9;f&#xE9;rence est celui de Jeff Patton, dispo en fran&#xE7;ais. La m&#xE9;thode a &#xE9;t&#xE9; pr&#xE9;sent&#xE9; de mani&#xE8;re parfaite par <a href="https://www.infoq.com/fr/presentations/art-maniement-exigences-agiles/?ref=donkey-blog-ddd-cqrs-event-sourcing-en-python">Alexandre Boutin dans une conf d&#xE9;di&#xE9;e en 2015</a>. Personnellement, et jusqu&apos;&#xE0; pr&#xE9;sent, c&apos;est ma technique pr&#xE9;f&#xE9;r&#xE9;e pour discuter du <u>besoin</u> avec un client ou un expert du domaine. Je la trouve naturelle et tr&#xE8;s souple. Bien que cette souplesse puisse conduire a des ateliers improductifs si on se concentre sur la technique davantage que sur les probl&#xE8;mes, ou les parcours de l&apos;utilisateur. Le story mapping, c&apos;est vraiement comme un story-board de production vid&#xE9;o, on d&#xE9;coupe les processus par &#xE9;tapes, tant qu&apos;on ne comprend pas exactement ce qu&apos;il y a dans une &#xE9;tape, et une fois que c&apos;est clair on passe &#xE0; la suite. Cette souplesse en fait un moyen id&#xE9;al d&apos;&#xE9;change et de mod&#xE9;lisation des processus, dans l&apos;espace du probl&#xE8;me pour comprendre le fonctionnement actuel, ou dans l&apos;espace de solution pour imaginer comment va fonctionner notre plate-forme demain. </p><p><strong>L&apos;event Storming</strong><br>Invent&#xE9; r&#xE9;cemment par Alebrto Brandolini, internet regorge de ressources sur le sujet, je vous laisse faire vos propres recherches. De mon point de vue cette m&#xE9;thode est int&#xE9;ressante, mais je trouve l&apos;approche trop technique, et pour certains profils qui ne seraient pas &#xE0; mon avis capable du niveau d&apos;abstraction n&#xE9;c&#xE9;ssaire. Bref pour moi, cela n&apos;est pas assez orient&#xE9; client, et trop orient&#xE9; sur le besoin des devs. </p><p><strong>Le domain story Telling</strong><br>Le petit nouveau des techniques d&apos;interview. Je trouve &#xE7;a hyper int&#xE9;ressant mais un peu verbeux, et peu lent. et de ce que j&apos;ai pu voir la technique r&#xE9;v&#xE8;le son plein potentiel &#xE0; une &#xE9;chelle un peu en dessous de la strat&#xE9;gie. Plus efficace donc pour mod&#xE9;liser le d&#xE9;tail d&apos;un sc&#xE9;nario d&apos;usage, qu&apos;un ensemble de parcours client. A utiliser dans un second temps, pour moi. </p><p>Bref tout &#xE7;a n&apos;est que mon avis &#xE9;videmment, et se discute totalement. Pour avancer, j&apos;ai donc organis&#xE9; un story mapping, dont voici le r&#xE9;sultat. <br><br><em>Disclaimer: comme tout le reste, un story mapping est valide &#xE0; un instant T, et devrait donc &#xE9;voluer avec le temps. Avec le temps la solution s&apos;affine, ouvre d&apos;autre perspectives, le contexte du projet &#xE9;volue... bref, s&apos;adapter au contexte est un peu obligatoire, mais le story mapping nous donne d&#xE9;j&#xE0; des infos sur la direction dans laquelle partir. </em></p><h3 id="le-pitch-de-latelier">Le pitch de l&apos;atelier</h3><p>Cadrer un atelier d&apos;&#xE9;change est hyper important. L&apos;introduction que j&apos;utilise est g&#xE9;n&#xE9;ralement &quot;Nous allons d&#xE9;crire ensemble les &#xE9;tape que vous franchissez aujourd&apos;hui pour faire votre m&#xE9;tier&quot; Cela permet aux expert de nous livrer la nature des t&#xE2;ches que nos intervenant r&#xE9;alisent, sans se focaliser sur les outils qui sont en jeu. C&apos;est le but du jeu : comprendre ce qu&apos;ils font, et pourquoi ils le font. Surtout pas comment. Si on tombe dans le comment on risque de se focaliser sur la solution que l&apos;on imagine, et nous n&apos;en sommes pas encore l&#xE0;. </p><h3 id="le-story-mapping-par-acteur"><br>Le story mapping par acteur</h3><p>En partant des besoins primaires list&#xE9;s &#xE0; l&apos;&#xE9;tape 3, nous avons construit les User Map ci dessous : <br><br><strong>Le Coach : </strong></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="http://donkeyblog.fr/content/images/2023/03/image-5.png" class="kg-image" alt="#4 - DDD Strat&#xE9;gique : Mod&#xE9;liser les parcours clients" loading="lazy" width="858" height="736" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-5.png 600w, http://donkeyblog.fr/content/images/2023/03/image-5.png 858w" sizes="(min-width: 720px) 720px"><figcaption>Story mapping de ce que fait un coach, dans une ligue &quot;manuelle&quot;</figcaption></figure><p>Nous avons donc au passage ajout&#xE9; quelques besoin qui n&apos;&#xE9;taient pas list&#xE9;s dans l&apos;article 3. <br></p><p><strong>Le Commissaire de ligue</strong></p><figure class="kg-card kg-image-card"><img src="http://donkeyblog.fr/content/images/2023/03/image-4.png" class="kg-image" alt="#4 - DDD Strat&#xE9;gique : Mod&#xE9;liser les parcours clients" loading="lazy" width="1352" height="975" srcset="http://donkeyblog.fr/content/images/size/w600/2023/03/image-4.png 600w, http://donkeyblog.fr/content/images/size/w1000/2023/03/image-4.png 1000w, http://donkeyblog.fr/content/images/2023/03/image-4.png 1352w" sizes="(min-width: 720px) 720px"></figure><p>Evidemment cette partie est beaucoup plus fournie. Le commissaire de ligue est notre cible principale, c&apos;est &#xE0; lui que nous allons rendre service au final, et c&apos;est lui qui est en charge de davantage de t&#xE2;ches. </p><p>Je pense pas qu&apos;il soit n&#xE9;c&#xE9;ssaire de pr&#xE9;senter en d&#xE9;tail le contenu des cartes, en toute logique elles sont suffisamment parlantes, que &#xE7;a soit pour la partie coach ou pour la partie commissaire de ligue. </p><p>Maintenant que nous avons identifi&#xE9; une premi&#xE8;re version des parcours client, l&apos;&#xE9;tape suivante va &#xEA;tre de regrouper ces parcours, s&#xE9;mantiquement parlant en domaine coh&#xE9;rents. Nous aurons ensuite davantage de facilit&#xE9; &#xE0; proposer une solution, elle aussi d&#xE9;coup&#xE9;e en contextes. Nous approcheront ainsi la d&#xE9;finition de nos contextes d&apos;utilisations, ou bounded contexts. <br></p><p>C&apos;est objectif de l&apos;article #5: D&#xE9;finir les domaines et sous-domaines</p>]]></content:encoded></item><item><title><![CDATA[#3 - DDD Stratégique : Identifier les acteurs et leurs besoins]]></title><description><![CDATA[Après avoir définit le problème, il faut imaginer comment approcher la solution en DDD]]></description><link>http://donkeyblog.fr/strategie-identifier-les-acteurs/</link><guid isPermaLink="false">64187650468b95005ba57df8</guid><category><![CDATA[DDD : Patterns stratégiques]]></category><dc:creator><![CDATA[Bagouze]]></dc:creator><pubDate>Fri, 24 Mar 2023 14:49:29 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1503095396549-807759245b35?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fGFjdG9yfGVufDB8fHx8MTY3OTY3Mzk4OA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1503095396549-807759245b35?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fGFjdG9yfGVufDB8fHx8MTY3OTY3Mzk4OA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="#3 - DDD Strat&#xE9;gique : Identifier les acteurs et leurs besoins"><p>Ou essayer de savoir un peu dans quelle direction se diriger, en premi&#xE8;re approximation.</p><h2 id="collecter-le-savoir-et-d%C3%A9finir-le-langage">Collecter le savoir et d&#xE9;finir le langage</h2><p>Lorsque l&apos;on d&#xE9;marre un projet de r&#xE9;alisation logicielle, la premi&#xE8;re partie, c&apos;est de comprendre le besoin. C&apos;est un peu enfoncer une porte ouverte me direz vous. Mais cette compr&#xE9;hension mutuelle va constituer les fondations de toute la suite. </p><p>L&apos;objectif de cette &#xE9;tape est donc double :<br>- transmettre une premi&#xE8;re connaissance m&#xE9;tier aux d&#xE9;veloppeurs<br>- d&#xE9;finir le langage que l&apos;on va utiliser dans la suite du projet.<br><br><strong>Transmettre le probl&#xE8;me</strong><br>Au d&#xE9;marrage, nous ne sommes pas encore, au moment ou je vous parle, capable d&apos;apporter une solution, pour une raison simple : &#xA0;nous ne connaissons pas le probl&#xE8;me m&#xE9;tier &#xE0; r&#xE9;soudre. <br>Les discussions avec nos experts vont donc avoir pour but d&apos;aider les &#xE9;quipes d&apos;ing&#xE9;nierie a cerner le <u>probl&#xE8;me</u>. Lorsque nous aurons list&#xE9; les acteurs et leurs &quot;pain-points&quot;, ce qu&apos;ils font aujourd&apos;hui, nous seront davantage en mesure de proposer une <u>solution</u>. <br><br><strong>Adopter un langage</strong><br>Ce langage, ou Ubiquitous Language dans la langue de Kanye West, permet de nommer de mani&#xE8;re non ambig&#xFC;e les actions et entit&#xE9;s de notre domaine m&#xE9;tier. Cette phase est &#xE9;galement cruciale, car savoir nommer ce dont on parle est juste la base pour assurer la compr&#xE9;hension des parties lors de tout le projet. <br>Une des techniques pour susciter l&apos;adoption est d&apos;&#xEA;tre vous m&#xEA;me irr&#xE9;prochable sur l&apos;emploi des termes. Quitte a reprendre l&apos;interlocuteur, lors de l&apos;emploi d&apos;un mauvais terme, si vous le d&#xE9;tectez. Au bout d&apos;un certain temps la pratique diffuse, et l&apos;adoption se fait. </p><p>En revanche, un conseil, attention a ne pas p&#xEA;cher par orgueil en voulant r&#xE9;inventer le vocabulaire m&#xE9;tier. C&apos;est surtout &#xE0; nous, d&#xE9;veloppeurs, d&apos;aller vers le client en adoptant son langage, autant que faire ce peut, en supprimant les synonymes ou les notions ambig&#xFC;es. Ce n&apos;est pas forc&#xE9;ment simple, mais c&apos;est obligatoire.</p><h2 id="les-acteurs-de-notre-domaine">Les acteurs de notre domaine</h2><p>Quels sont les grand type d&apos;intervenants dans l&apos;organisation et le suivi d&apos;une comp&#xE9;tition ?</p><ul><li><strong>Le coach : </strong><br>Le gars ( ou la meuf ) qui participe &#xE0; une ligue ou un tournoi. Pour m&#xE9;moire, la ligue c&apos;est un match par mois avec les &#xE9;quipes qui progressent au fil du temps, un tournoi c&apos;est 5 match en un week-end, sans que les &#xE9;quipes ne progressent.<br></li><li><strong>Le commissaire de ligue : </strong><br>Le chef d&apos;une ligue. Celui qui organise les journ&#xE9;es de rencontre, qui saisit les rapports de matchs pour que les &#xE9;quipes progressent, qui motive les joueurs &#xE0; venir effectivement jouer leur match pour que la comp&#xE9;tition progresse. Les commissaires de ligue sont &#xE9;videmment &#xE9;galement des coachs dans 95% du temps. </li></ul><h2 id="les-besoins-de-nos-acteurs">Les besoins de nos acteurs </h2><p>Et que font ils ces braves gens ? </p><p><strong>Le coach : </strong><br>Lui est l&#xE0; en consommateur.<br>- Il vient aux soir&#xE9;es de jeu, quand il y pense ou quand son commissaire lui rappelle.<br>- Il joue ses matchs, et notes ses actions sur une feuille de match. Ces actions rapporteront de l&apos;exp&#xE9;rience &#xE0; son &#xE9;quipe, qui deviendra plus forte. Il note aussi les blessures que son &#xE9;quipe &#xE0; inflig&#xE9; &#xE0; l&apos;&#xE9;quipe d&apos;en face. Qui par cons&#xE9;quent deviendra moins forte, &#xE0; cause des dites blessures.<br>- a la fin du match il donne la feuille de match a son commissaire de ligue. <br>- quand son &#xE9;quipe a &#xE9;t&#xE9; mise &#xE0; jour par le commissaire, il va regarder quand est la prochaine journ&#xE9;e de ligue, et contre qui il joue, si l&apos;info est disponible. Il regardera aussi son classement pour voir si il a des chances de remporter la ligue cette ann&#xE9;e. <br><br><strong>Le commissaire de ligue : </strong><br>Il organise un peu tout le bastringue. <br>- il bat le rappel pour la prochaine journ&#xE9;e, pour que tout le monde soit l&#xE0;<br>- il joue son match comme les autres coach<br>- il collecte les feuilles de matchs en fin de journ&#xE9;e<br>- il fait &#xE9;voluer chaque &#xE9;quipe en fonction de chaque action ou blessure de chaque match. <br>- il pr&#xE9;vient les joueurs que les &#xE9;quipes sont a jour, et leur demande de v&#xE9;rifier que tout est OK<br>- il corrige les erreurs contenues dans les feuilles de match en les modifiant<br>- il met &#xE0; jour le classement<br><br>Le m&#xE9;tier de commissaire de ligue est une plaie.<br><br>Quoi qu&apos;il en soit nous connaissons d&#xE9;sormais les activit&#xE9;s de nos acteurs, dans le domaine qui nous int&#xE9;resse. Ces activit&#xE9;s sont essentiellement manuelle. Par exemple le fait de battre le rappel consiste &#xE0; envoyer des sms, des messages sur des forum ou sur whatsapp. La saisie de feuille de match est m&#xEA;me parfois r&#xE9;alis&#xE9;e via excel, avant que tout ne soit calcul&#xE9; &#xE0; la mano, pour finalement que les nouvelles versions d&apos;&#xE9;quipe ne soient envoy&#xE9;es par mail en version PDF. Si il y a beaucoup de joueurs, cela peut prendre un temps cons&#xE9;quent, plusieurs heures.<br><br>La prochaine &#xE9;tape va donc &#xEA;tre d&apos;imaginer comment nous allons mod&#xE9;liser les parcours clients de nos acteurs, au sein d&apos;une solution qui leur simplifierait l&apos;existence. L&apos;exercice est assez fun, puisqu&apos;&#xE0; ce stade l&apos;imagination sera notre seule limite. </p><p><a href="http://donkeyblog.fr/4-ddd-strategique-modeliser-les-parcours-client/">C&apos;est l&apos;article #4 qui traite de ce sujet. </a><br></p><p></p>]]></content:encoded></item><item><title><![CDATA[#2 - DDD Stratégique : Le plan d'attaque]]></title><description><![CDATA[Comment aborder un projet de réalisation logiciel guidé par une démarche Domain Driven Design]]></description><link>http://donkeyblog.fr/le-plan-dattaque/</link><guid isPermaLink="false">641b095213a754005b79be56</guid><category><![CDATA[DDD : Patterns stratégiques]]></category><dc:creator><![CDATA[Bagouze]]></dc:creator><pubDate>Wed, 22 Mar 2023 16:54:18 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1619468129361-605ebea04b44?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDR8fG1hcHxlbnwwfHx8fDE2Nzk0OTc2NTc&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1619468129361-605ebea04b44?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDR8fG1hcHxlbnwwfHx8fDE2Nzk0OTc2NTc&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="#2 - DDD Strat&#xE9;gique : Le plan d&apos;attaque"><p></p><p>Le DDD regroupe tellement de recettes que c&apos;est assez compliqu&#xE9; d&apos;identifier un bout par lequel d&#xE9;buter, lorsqu&apos;on veut s&apos;y essayer. </p><p>Classiquement le Domain Driven Design propose deux niveaux d&apos;action :la strat&#xE9;gie et la tactique. La strat&#xE9;gie pour la vue de haut et la tactique pour les d&#xE9;tails, en r&#xE9;sum&#xE9;.</p><p><strong>Phase Strat&#xE9;gique : </strong>L&apos;objectif est de cerner le probl&#xE8;me auquel on s&apos;attaque. Donc de permettre aux d&#xE9;veloppeurs de comprendre les enjeux, les entit&#xE9;s, les probl&#xE9;matiques... bref l&apos;univers auquel on s&apos;adresse. Phase assez cruciale, mais aussi un peu intimidante car il est tr&#xE8;s rare que l&apos;on comprenne int&#xE9;gralement et rapidement les enjeux de la digitalisation de processus complexes. Cette phase est classiquement support&#xE9;e par des m&#xE9;thodes et des ateliers qui visent a discuter avec les experts du domaine pour s&apos;approprier une partie de leur savoir. </p><p><strong>Phase Tactique: </strong>Ici, les devs sont davantage en zone de confort, car on parle technique. Les patterns tactiques regroupent un ensemble de bonne pratiques de code, pour r&#xE9;aliser notre impl&#xE9;mentation DDD. Ces bonnes pratiques visent &#xE0; assurer que la mod&#xE9;lisation strat&#xE9;gique du probl&#xE8;me faite pr&#xE9;alablement ne va pas se retrouver noy&#xE9;e au milieu d&apos;enjeux purement techniques et exog&#xE8;nes &#xE0; notre probl&#xE9;matique m&#xE9;tier. <br><br>Et il y a &#xE9;videmment une boucle de r&#xE9;tro-action entre ces phases. Nous allons d&#xE9;finir une premi&#xE8;re approche strat&#xE9;gique, puis en faire une impl&#xE9;mentation. C&apos;est lors de leur de l&apos;impl&#xE9;mentation que nous allons nous confronter aux limites de pertinence de notre premi&#xE8;re approche strat&#xE9;gique. </p><p>Donc nous allons potentiellement red&#xE9;couper, et r&#xE9;agencer les domaines. et modifier le code en fonction. On va essayer de ne pas faire &#xE7;a trop trop souvent histoire de ne pas cramer tout le temps en refacto mais bon vous voyez l&apos;id&#xE9;e.<br><br>Le plus naturel pour notre gestionnaire de ligue de football fantastique est de commencer par l&apos;aspect strat&#xE9;gique. En gros essayer d&apos;avoir une vue d&apos;avion de notre sujet. Essayer de capturer la probl&#xE9;matique d&apos;ensemble. <br><br>Cette partie est d&#xE9;taill&#xE9;e dans l&apos;article suivant, <a href="http://donkeyblog.fr/strategie-identifier-les-acteurs/">en commencant par identifier les acteurs de notre domaine</a>. </p><p>Ensuite nous verrons quels sont les moyens d&apos;impl&#xE9;mentation que nous avons choisi pour traiter nos probl&#xE9;matiques. <br>La route est encore longue avant d&apos;avoir une appli qui tourne. </p>]]></content:encoded></item><item><title><![CDATA[#1 - DonkeyBlog : DDD par l'exemple.]]></title><description><![CDATA[Retour d'expérience de l'utilisation du Domain Driven Design, basé sur un exemple concret, de A à Z]]></description><link>http://donkeyblog.fr/ddd-par-l-exemple/</link><guid isPermaLink="false">6418d00e468b95005ba57f3f</guid><category><![CDATA[Introduction]]></category><dc:creator><![CDATA[Bagouze]]></dc:creator><pubDate>Tue, 21 Mar 2023 19:42:29 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1634269093262-4da36a033781?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDd8fGZvb3RiYWxsJTIwdXN8ZW58MHx8fHwxNjc5MzUyOTc3&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<h3></h3><img src="https://images.unsplash.com/photo-1634269093262-4da36a033781?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDd8fGZvb3RiYWxsJTIwdXN8ZW58MHx8fHwxNjc5MzUyOTc3&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="#1 - DonkeyBlog : DDD par l&apos;exemple."><p>Tous les principes d&apos;architecture logicielle para&#xEE;ssent toujours lumineux quand ils sont expliqu&#xE9;s. En gros tout est toujours merveilleux dans le meilleurs des mondes. </p><p>Ce type d&apos;explication est souvent st&#xE9;rile car sans cas d&apos;application il est difficile de saisir les d&#xE9;tails ou les limites des principes en question. </p><p>Pour &#xE9;prouver notre approche du DDD, nous avons un peu tout essay&#xE9;. Des ateliers, des conf&#xE9;rences, des webinairs... mais a&apos;ment donn&#xE9;, pour faire du cheval, il faut monter sur un cheval. <br>Nous avons donc du impl&#xE9;menter un cas re&#xE9;l, issu d&apos;un besoin existant, en DDD, sur une archi mixte CRUD / CQRS / Event sourcing. </p><p>Toutefois, nous ne pouvions pas prendre le risque d&apos;essayer des pattern et des architectures nouvelles sur un projet client. Les clients sont l&#xE0; pour &#xEA;tre servis le plus efficacement possible, pas pour nous payer une formation. <br>Par ailleurs nous n&apos;aurions pas pu d&#xE9;voiler des d&#xE9;tails d&apos;impl&#xE9;mentation d&apos;un projet client, pour des raisons &#xE9;videntes de confidentialit&#xE9;. Et ce retour d&apos;exp&#xE9;rience nous para&#xEE;ssait int&#xE9;ressant, car nous n&apos;avions rien trouv&#xE9; d&apos;&#xE9;quivalent. </p><p>Nous avons donc pris la d&#xE9;cision de mettre notre d&#xE9;marche DDD &#xE0; l&apos;&#xE9;preuve des balles sur un projet side. Un projet non-commercial, qui n&apos;aurait pas d&apos;autre but que de servir ses utilisateurs gratuitement, et d&apos;aiguiser notre connaissance en DDD donc. </p><p>Nous aurons ainsi tout le loisir de d&#xE9;tailler notre architecture, notre d&#xE9;marche de mod&#xE9;lisation tactique et strat&#xE9;gique, afin de donner du corps &#xE0; l&apos;ensemble, et donc de tester tous nos choix &#xE0; l&apos;aune d&apos;un cas r&#xE9;&#xE9;l, sans pour autant mettre qui que ce soit en porte-&#xE0;-faux. </p><h3 id="lobjectif-m%C3%A9tier">L&apos;objectif m&#xE9;tier</h3><p>L&apos;application Roxana est destin&#xE9;e &#xE0; g&#xE9;rer des ligues et des tournois d&apos;un jeu de plateau. Un jeu que les plus geeks (et les plus vieux) d&apos;entre vous connaissent peut-&#xEA;tre d&#xE9;j&#xE0; : </p><!--kg-card-begin: markdown--><p><strong>Bloodbowl</strong></p>
<!--kg-card-end: markdown--><p>Le jeu de football US fantastique &#xE9;dit&#xE9; par GameS Workshop depuis 40 ans environ. </p><p>Ce jeu met en sc&#xE8;ne deux &#xE9;quipes qui s&apos;affrontent dans un match qui s&apos;approche du foot am&#xE9;ricain, en un poil plus violent et un poil plus fourbe. <br>Il y a donc dans la vie r&#xE9;&#xE9;lle des clubs de gens qui se r&#xE9;unissent pour jouer des matchs de bloodbowl sur un plateau, un peu comme ou joue aux dames ou aux &#xE9;checs. </p><p>A l&apos;issue d&apos;un match les &#xE9;quipes ont progress&#xE9;, les joueurs ont potentiellement encaiss&#xE9; des blessures. Elles ont &#xE9;galement amass&#xE9; de l&apos;or en fonction de l&apos;affluence. Ce pognon permettra d&apos;acheter de nouveaux joueurs, ou du staff qui donnera des bonus lors du prochain match. Rien de bien compliqu&#xE9;, quoi que.</p><p>Cette gestion de l&apos;&#xE9;volution des &#xE9;quipes est relativement fastidieuse car bard&#xE9; de calculs... et de r&#xE8;gles m&#xE9;tier. &#xA0;J&apos;ai donc cr&#xE9;e il y a quelques ann&#xE9;es un site qui permettait d&apos;automatiser toute cette phase, ainsi que le calcul des points de classement de chaque &#xE9;quipe. Passage oblig&#xE9; pour savoir en fin de saison qui a d&#xE9;croch&#xE9; le titre tant convoit&#xE9; de champion de bloodbowl de <a href="https://www.saint-simon.fr/?ref=donkey-blog-ddd-cqrs-event-sourcing-en-python">Saint Simon De Pelouaille.</a></p><p>Le site en question est vieillissant, nous avons donc d&#xE9;cider d&apos;en r&#xE9;&#xE9;crire une version, en appliquant l&apos;ensemble des patterns du DDD, pour r&#xE9;aliser un objectif concret. </p><p>Cet objectif pr&#xE9;sente beaucoup d&apos;avantages :</p><ul><li>les r&#xE8;gles de gestion d&apos;une ligue et des progression des &#xE9;quipes sont relativement complexes, ce qui nous donne des cas d&apos;usage suffisamment int&#xE9;ressants pour &#xE9;prouver notre d&#xE9;marche DDD et les diff&#xE9;rents styles d&apos;architectures logicielle cibl&#xE9;s. Il y a m&#xEA;me certains concepts de progressions temporelles qui semblent un terrain de jeu id&#xE9;al pour faire de l&apos;event sourcing.</li><li>Le contexte et les concepts m&#xE9;tier en tant que tels ne sont pas tr&#xE8;s compliqu&#xE9;s &#xE0; se repr&#xE9;senter. Nous allons parler d&apos;&#xE9;quipe, de matchs, de classement, de joueurs, de coachs etc. Donc des concepts assez simple &#xE0; prendre en main au premier abord, ce qui permet au lecteur occasionnel de ne pas &#xEA;tre totalement largu&#xE9;. </li><li>Il y a d&#xE9;j&#xE0; des utilisateurs ( environ 500 &#xE0; la louche ) ce qui donne &#xE0; l&apos;ensemble une certaine r&#xE9;alit&#xE9;. En gros, il y a des vrais gens qui vont se servir de notre syst&#xE8;me. Et qui vont gueuler si &#xE7;a ne marche pas. </li><li>On a les experts du domaine sous la main, donc cela sera simple de mener des ateliers pour formaliser l&apos;ubiquitous language et l&apos;analyse fonctionnelle strat&#xE9;gique</li></ul><h3 id="une-premi%C3%A8re-liste-de-fonction">Une premi&#xE8;re liste de fonction</h3><p>En toute logique cette premi&#xE8;re liste de fonction doit &#xEA;tre issue de la partie strat&#xE9;gique de notre d&#xE9;marche Domain Driven Design, mais je d&#xE9;flore un peu le sujet en amont, pour permettre &#xE0; tout le monde de voir un peu mieux l&#xE0; ou nous allons mettre les pieds. <br>En premi&#xE8;re approximation, le syst&#xE8;me doit permettre de : <br>- g&#xE9;rer le cycle de vie d&apos;un club, avec ses comp&#xE9;titions et les calendrier aff&#xE9;rents<br>- cr&#xE9;er des saisons, les poules, les r&#xE8;gles de classement<br>- Permettre au joueurs demander &#xE0; inscrire une de leur &#xE9;quipe sur une comp&#xE9;tition, demande qui devra &#xEA;tre valid&#xE9;e par un commissaire de la comp&#xE9;tition en question <br>- Saisir des rapports de matchs, avec une double validation des joueurs avant publication. Il devra &#xE9;galement &#xEA;tre possible de d&#xE9;-publier un rapport pour le corriger et appliquer les nouveaux changements induits. <br>- Calculer les progressions des joueurs et des &#xE9;quipes<br><br>Mais aussi de : <br>- pr&#xE9;senter son club au travers d&apos;une page d&#xE9;di&#xE9;e et administrable simplement<br>- pr&#xE9;senter une comp&#xE9;tition au travers d&apos;une page d&#xE9;di&#xE9;<br>- &#xE9;crire des articles de fluff, ou de rapport narratif de match<br><br>Pas mal de choses en fait. <br>Pas mal de choses simples, ou moins simples. <br><br>Voila donc la probl&#xE9;matique, que nous nous proposons de r&#xE9;soudre et automatiser, gr&#xE2;ce au Domain Driven Design, tout au long des articles de ce site. </p><p>Nous allons d&apos;ailleurs commencer directement avec la partie strat&#xE9;gique du Domain Driven Design, <a href="http://donkeyblog.fr/le-plan-dattaque/">via un article qui pr&#xE9;sente le plan de bataille que nous allons suivre. </a><br><br><br></p>]]></content:encoded></item><item><title><![CDATA[#0 - Bientôt]]></title><description><![CDATA[<p><a href="#/portal/">U</a>n blog sur la tech, le python, le DDD, l&apos;architecture logicielle... bref plein de trucs cools. </p><p>Avec beaucoup de python dedans. </p>]]></description><link>http://donkeyblog.fr/coming-soon/</link><guid isPermaLink="false">6418231863549c00ba25fdb2</guid><category><![CDATA[News]]></category><dc:creator><![CDATA[Bagouze]]></dc:creator><pubDate>Mon, 20 Mar 2023 09:10:48 GMT</pubDate><media:content url="http://donkeyblog.fr/content/images/2023/03/dcb.png" medium="image"/><content:encoded><![CDATA[<img src="http://donkeyblog.fr/content/images/2023/03/dcb.png" alt="#0 - Bient&#xF4;t"><p><a href="#/portal/">U</a>n blog sur la tech, le python, le DDD, l&apos;architecture logicielle... bref plein de trucs cools. </p><p>Avec beaucoup de python dedans. </p>]]></content:encoded></item></channel></rss>