Académique Documents
Professionnel Documents
Culture Documents
Domain-Driven
Design Vite fait
Domain-Driven Design
Vite fait
Conformiste ..............................................................................................................71
Couche anticorruption...............................................................................................73
Chemins spars......................................................................................................75
Service Hte ouvert ..................................................................................................76
Distillation .................................................................................................................77
6
nombreux exemples et tudes de cas fournies dans le livre dEric ou aux exemples de
terrain proposs dans le livre de Jimmy. Je vous encourage vivement lire lun et
lautre de ces deux excellents ouvrages. En attendant, si vous pensez que la
communaut a besoin que DDD fasse partie de notre conscience collective, nhsitez
pas parler autour de vous de ce livre et du travail dEric.
Floyd Marinescu
Co-fondateur et Chief Editor dInfoQ.com
Introduction
Les logiciels sont des instruments crs pour nous aider traiter la complexit de la
vie moderne. Les logiciels sont juste un moyen pour nous datteindre un but, et
gnralement ce but est quelque chose de tout fait pratique et rel. Par exemple nous
utilisons des logiciels pour le contrle du trafic arien, ce qui est directement reli au
monde qui nous entoure. Nous voulons aller dun endroit un autre par la voie des
airs, et pour a nous utilisons une machinerie sophistique, alors nous crons des
logiciels pour coordonner les vols des milliers davions qui se trouvent dans le ciel
toute heure.
Les logiciels doivent tre pratiques et utiles ; autrement nous ninvestirions pas autant
de temps et de ressources dans leur cration. Cela les rend minemment relis un
certain aspect de nos vies. Un paquetage logiciel utile ne peut pas tre dcorrl de
cette sphre de ralit : le domaine quil est cens nous aider grer. Au contraire, le
logiciel y est profondment entreml.
La conception de logiciels est un art, et comme tout art elle ne peut pas tre enseigne
et apprise comme une science prcise, au moyen de thormes et de formules. Nous
pouvons dcouvrir des principes et des techniques utiles appliquer tout au long du
processus de cration de logiciel, mais nous ne serons probablement jamais capables
de fournir un chemin exact suivre en partant du besoin du monde rel pour arriver
jusquau module de code destin rpondre ce besoin. Comme une photo ou un
btiment, un produit logiciel contiendra toujours la touche personnelle de ceux qui
lont conu et dvelopp, un petit quelque chose du charisme et du flair (ou du manque
de flair) de ceux qui ont contribu sa naissance et sa croissance.
Il y a diffrentes manires daborder la conception logicielle. Ces 20 dernires annes,
lindustrie du logiciel a connu et utilis plusieurs mthodes pour crer ses produits,
chacune avec ses avantages et ses inconvnients. Lobjectif de ce livre est de se
focaliser sur une mthode de conception qui a merg et volu au cours des deux
dernires dcennies, mais sest plus distinctement cristallise depuis quelques annes :
la conception dirige par le domaine. Eric Evans a grandement contribu la question
en couchant sur le papier dans un unique livre une grande part de la connaissance
accumule sur la conception dirige par le domaine. Pour une prsentation plus
dtaille du sujet, nous vous recommandons la lecture de son livre Domain-Driven
Design: Tackling Complexity in the Heart of Software publi par Addisson-Wesley,
ISBN: 0-321-12521-5.
1
Quest-ce que Domain Driven Design ?
Le dveloppement logiciel est le plus souvent employ pour automatiser des processus
qui existent dj dans le monde rel, ou pour fournir des solutions des problmes
mtier rels. Ces processus mtier automatiser ou ces problmes du monde rel que
le logiciel traite constituent le domaine du logiciel. Nous devons comprendre ds le
dpart que le logiciel trouve son origine dans ce domaine et lui est profondment li.
Les logiciels sont faits de code. Nous pourrions tres tents de passer trop de temps sur
le code, et voir les logiciels simplement comme des objets et des mthodes.
Pensez la mtaphore de la fabrication de voitures. Les travailleurs impliqus dans la
construction automobile peuvent se spcialiser dans la production de pices de voiture,
mais ce faisant ils ont souvent une vision limite du processus de fabrication
automobile dans son ensemble. Ils commencent voir la voiture comme un norme
assemblage de pices qui doivent aller les unes avec les autres, mais une voiture est
bien plus que cela. Une bonne voiture, a commence par une vision. Cela commence
par des spcifications crites avec soin. Et a se poursuit avec de la conception.
Beaucoup, beaucoup de conception. Des mois, peut-tre des annes passes sur la
conception, la modifier et la raffiner jusqu ce quelle atteigne la perfection,
jusqu ce quelle reflte la vision originale. Le processus de conception ne se fait pas
entirement sur papier. Une grande partie consiste fabriquer des modles de la
voiture, et les tester sous certaines conditions pour vrifier quils marchent. On
modifie la conception sur la base des rsultats de ces tests. Finalement, la voiture est
envoye en production, et les pices sont cres et assembles.
Le dveloppement logiciel est similaire. On ne peut pas se contenter de rester assis et
taper du code. On peut le faire, et a marche bien pour des cas triviaux. Mais on ne
peut pas crer des logiciels complexes de cette manire.
Pour crer un bon logiciel, vous devez savoir de quoi il y est question. Vous ne pouvez
pas crer un systme logiciel bancaire moins davoir une bonne comprhension de ce
quest la banque, vous devez comprendre le domaine de la banque.
10
Est-il possible de crer un logiciel bancaire complexe sans une bonne connaissance du
domaine ? Pas une seconde. Jamais. Qui sy connait en banque ? Larchitecte logiciel ?
Non. Il utilise juste une banque pour sassurer que son argent est en scurit et
disponible quand il en a besoin. Lanalyste logiciel ? Pas vraiment. Il sait analyser un
sujet prcis, quand on lui donne tous les lments ncessaires. Le dveloppeur ? Vous
pouvez tout de suite oublier. Qui, alors ? Les banquiers, bien sr. Le systme bancaire
est trs bien compris par les gens de lintrieur, par ses spcialistes. Ils en connaissent
tous les dtails, tous les piges, tous les problmes possibles, toutes les rgles. Voil
par o lon devrait toujours commencer : le domaine.
Lorsque nous dbutons un projet informatique, nous devrions nous concentrer sur le
domaine dans lequel il opre. Le seul but du logiciel est damliorer un domaine
spcifique. Pour tre capable de faire cela, le logiciel doit se mettre au diapason du
domaine pour lequel il a t cr. Sans cela, il introduira des tensions dans le domaine,
provoquant des dysfonctionnements, des dgts, voire mme semant le chaos.
Comment peut-on mettre le logiciel au diapason du domaine ? La meilleure faon dy
arriver est de faire du logiciel un reflet du domaine. Le logiciel doit incorporer les
concepts et lments qui sont au cur du domaine, et saisir avec prcision les relations
entre eux. Le logiciel doit modliser le domaine.
Quelquun qui na pas de connaissances bancaires doit pouvoir en apprendre beaucoup
en lisant simplement le code du modle du domaine. Cest essentiel. Un logiciel dont
les racines ne sont pas enfouies profondment dans le domaine ne ragira pas bien au
changement au fil du temps.
On commence donc par le domaine. Quoi dautre ensuite ? Un domaine est une chose
qui appartient ce bas-monde. On ne peut pas juste le prendre et le verser sur le
clavier afin quil rentre dans lordinateur et devienne du code. Il nous faut crer une
abstraction du domaine. On en apprend beaucoup sur un domaine quand on parle avec
les experts du domaine. Mais cette connaissance brute ne sera pas facilement
transformable en des constructions logicielles, moins que nous en fabriquions une
abstraction, un schma dans notre esprit. Au dbut, le schma est toujours incomplet.
Mais avec le temps, en travaillant dessus, nous lamliorons et il devient de plus en
plus clair pour nous. Quest-ce que cette abstraction ? Cest un modle, un modle du
domaine. Selon Eric Evans, un modle du domaine nest pas un diagramme
particulier ; cest lide quon cherche vhiculer travers le diagramme. Ce nest pas
simplement la connaissance contenue dans le cerveau dun expert du domaine ; cest
une abstraction rigoureusement organise et slective de cette connaissance. Un
diagramme peut reprsenter et communiquer un modle, comme peut le faire un code
soigneusement crit, comme peut le faire aussi une phrase en franais.
11
Le modle est notre reprsentation interne du domaine cibl, et elle est absolument
ncessaire tout au long de la conception comme du processus de dveloppement.
Pendant la conception, nous nous remmorons le modle et nous nous y rfrons de
nombreuses fois. Le monde qui nous entoure reprsente bien plus que ce que nos
cerveaux peuvent traiter. Mme un domaine spcifique pourrait bien tre plus que ce
quun esprit humain peut manier la fois. Nous devons organiser linformation, la
systmatiser, la diviser en plus petits morceaux, regrouper ces morceaux dans des
modules logiques, en prendre un la fois et le traiter. Il nous faut mme laisser de ct
certaines parties du domaine. Un domaine contient simplement une masse trop grande
dinformation pour linclure toute entire dans le modle. Et pour une grande partie, il
nest mme pas ncessaire de la prendre en compte. Cest un dfi en soi. Que garder et
quoi jeter ? Ca fait partie de la conception, du processus de cration logicielle. Le
logiciel bancaire gardera surement une trace de ladresse du client, mais il ne devrait
pas soccuper de la couleur de ses yeux. Cest un exemple vident, mais il peut y en
avoir dautres moins flagrants.
Un modle est une partie essentielle dune conception logicielle. Nous en avons besoin
pour pouvoir grer la complexit. Toute notre mcanique de raisonnement sur le
domaine est synthtise dans ce modle. Tout a est trs bien, mais cela doit sortir de
notre esprit. Ce nest pas trs utile si a y reste enferm, vous ne croyez pas ? Nous
devons communiquer ce modle aux experts du domaine, nos collgues concepteurs,
et aux dveloppeurs. Le modle est lessence du logiciel, mais nous devons inventer
des faons de lexprimer, de le transmettre aux autres. Nous ne sommes pas tout seuls
dans ce processus, nous devons donc partager la connaissance et linformation, et nous
devons le faire bien, prcisment, compltement et sans ambigit. Il y a diffrentes
manires de le faire. Lune est graphique : diagrammes, cas dutilisation, dessins,
photos, etc. Lautre est de lcrire. De coucher sur le papier notre vision du domaine.
Une autre encore est le langage. Nous pouvons et nous devrions crer un langage pour
communiquer des problmes spcifiques du domaine. Nous dtaillerons tous ces
moyens plus tard, mais lide principale est que nous devons communiquer le modle.
Lorsque notre modle est exprim, on peut commencer concevoir le code. Ce qui est
diffrent de concevoir le logiciel. Concevoir le logiciel, cest comme imaginer
larchitecture dune maison, cest porter un il global sur ldifice. A linverse,
concevoir le code cest travailler les dtails, comme lemplacement dun tableau sur tel
ou tel mur. Le design du code est tout aussi important, mais pas aussi fondamental que
la conception du logiciel. Une erreur dans le design du code se corrige dhabitude
facilement, tandis que les erreurs de conception du logiciel sont beaucoup plus
coteuses rparer. Cest une chose de dplacer un tableau un peu plus gauche, mais
cen est une toute autre de dmolir un ct de la maison pour le refaire diffremment.
Nanmoins, le produit final ne sera pas bon sans un bon design du code. Cest l que
les design patterns de code savrent pratiques, et on devrait toujours les appliquer
12
13
14
OK, lavion dcolle dun endroit et touche le sol dans un autre. Mais que se passe-t-il
en lair ? Quel chemin de vol suit-il ? En vrit, nous nous intressons davantage ce
qui se passe une fois quil est en lair. Laiguilleur dit quon assigne chaque avion un
plan de vol qui est cens dcrire le voyage arien en entier. Lorsque vous entendez
parler de plan de vol, vous pouvez penser dans votre for intrieur quil sagit du
chemin suivi par lavion dans le ciel. En discutant plus avant, vous notez un mot
intressant : route. Ce mot capte votre attention immdiatement, et ce pour une bonne
raison. La route reprsente un concept important en matire de transport arien. Cest
ce que les avions font en volant, ils suivent une route. Il est vident que le dpart et la
destination de laronef sont aussi les points de dbut et de fin de la route. Donc au
lieu dassocier lappareil aux points de dpart et de destination, il semble plus naturel
de le relier une route, qui son tour est associe au dpart et la destination
correspondants.
En parlant avec laiguilleur des routes suivies par les avions, vous dcouvrez que la
route est en fait forme de petits segments qui, mis bout bout, constituent une sorte
de ligne tortueuse allant du dpart la destination. La ligne est cense passer par des
points fixes dtermins lavance. Donc, une route peut tre considre comme une
srie de positions conscutives. A ce niveau, vous ne voyez plus le dpart et la
destination comme les points terminaux de la route, mais juste comme deux positions
parmi dautres. Cest probablement assez diffrent de la faon dont les voit
15
laiguilleur, mais il sagit dune abstraction ncessaire qui sera utile plus tard. Les
changements rsultant de ces dcouvertes sont les suivants :
Le diagramme montre un autre lment : le fait que chaque position est un point de
lespace suivi par la route, et elle est exprime sous forme dun point en 3 dimensions.
Mais en parlant laiguilleur, vous allez dcouvrir quil ne le voit pas de la mme
manire. En fait, il voit la route comme une projection sur Terre du vol de lavion. Les
positions sont juste des points la surface de la Terre dtermins de manire unique
par leur latitude et leur longitude. Le diagramme correct est donc :
Que se passe-t-il ici en ralit ? Vous et les experts du domaine, vous tes en train de
parler, dchanger de la connaissance. Vous commencez poser des questions, et ils
vous rpondent. Ce faisant, ils font ressortir des concepts essentiels du domaine du
trafic arien. Il est possible que ces concepts sortent mal dgrossis et dsorganiss,
mais ils sont nanmoins essentiels pour comprendre le domaine. Il vous faut en
apprendre le plus possible sur le domaine de la part des experts. Et en glissant les
bonnes questions, en traitant linformation de la bonne manire, vous et les experts
allez commencer esquisser une vue du domaine, un modle du domaine. Cette vue
16
nest ni complte ni juste, mais cest le point de dpart dont vous avez besoin. Essayez
de comprendre les concepts essentiels du domaine.
Cest une partie importante du design. Dhabitude, de longues discussions ont lieu
entre les architectes logiciels ou les dveloppeurs et les experts du domaine. Les
spcialistes logiciels veulent extraire la connaissance des experts du domaine, et ils
doivent aussi la transformer en une forme utile. Arrivs un certain point, ils
pourraient avoir envie de crer un premier prototype pour voir comment a marche
ce moment-l. Ce faisant, il est possible quils rencontrent certains problmes dans
leur modle ou leur approche, et quils veuillent changer le modle. La communication
ne se fait pas seulement dans un sens, des experts du domaine vers larchitecte logiciel
puis vers les dveloppeurs. Il y a aussi des retours, qui aident crer un meilleur
modle ainsi quune comprhension plus claire et plus juste du domaine. Les experts
du domaine connaissent bien leur terrain dexpertise, mais ils organisent et utilisent
leur connaissance dune manire spcifique, qui nest pas toujours la bonne pour une
implmentation dans un systme logiciel. Lesprit danalyse du concepteur du logiciel
aide dnicher certains concepts-cls du domaine lors des discussions avec les
experts, et aide aussi construire une structure pour de futures discussions comme
nous le verrons au chapitre suivant. Nous, les spcialistes en logiciel (architectes
logiciels et dveloppeurs), et les experts du domaine, crons le modle du domaine
ensemble, et le modle est lendroit o ces deux champs dexpertise se rencontrent. Ce
processus peut sembler trs gourmand en temps, et cest le cas, mais cest comme a
quil doit tre, parce quau final le but du logiciel est de rsoudre des problmes mtier
dans un domaine de la vie relle, et il doit donc se fondre parfaitement dans le
domaine.
17
2
Le Langage omniprsent
18
design qui ncessitent dtre examins et insrs dans la conception globale. Tout cela
nest pas possible sans un langage commun.
Les langages napparaissent pas du jour au lendemain. Ca demande un srieux travail
et beaucoup de concentration pour sassurer que les lments cls du langage voient le
jour. Il nous faut trouver ces concepts cls qui dfinissent le domaine et la conception,
trouver les mots qui leur correspondent, et commencer les utiliser. Certains dentre
eux sont faciles reprer, mais il y en a des plus ardus.
Eliminez les difficults en testant des expressions diffrentes, qui refltent des modles
alternatifs. Puis refactorez le code, en renommant les classes, les mthodes et les
modules pour vous conformer au nouveau modle. Trouvez une solution au flou
entourant certains termes grce la conversation, exactement de la mme manire
quon saccorde sur la signification de mots ordinaires.
Construire un langage comme cela conduit un rsultat manifeste : le modle et le
langage sont fortement interconnects lun lautre. Un changement dans le langage
doit devenir un changement dans le modle.
Les experts du domaine devraient sopposer des termes et des structures maladroites
ou inaptes vhiculer la comprhension du domaine. Sil y a des choses que les
experts du domaine ne comprennent pas dans le modle ou le langage, alors il est plus
que probable que quelque chose cloche dans ce dernier. Dun autre ct, les
dveloppeurs devraient surveiller les ambiguts et les incohrences qui auront
tendance apparaitre dans la conception.
20
Expert : Oh, non. Les pilotes reoivent une route suivre. Et ils doivent rester aussi
proches que possible de cette route.
Dveloppeur : Je vois cette route comme un chemin en 3D dans le ciel. Si nous
utilisons un systme de coordonnes cartsiennes, alors la route est simplement une
srie de points 3D.
Expert : Je ne pense pas. Nous ne voyons pas la route comme a. La route est en fait
la projection sur le sol du chemin arien attendu de lappareil. La route passe par une
srie de points au sol dtermins par leur latitude et longitude.
Dveloppeur : OK, appelons alors chacun de ces points une position, puisque cest un
point fixe la surface de la Terre. Ensuite on utilisera une srie de points 2D pour
dcrire le chemin. Et au passage, le dpart et la destination sont simplement des
positions. On ne devrait pas les considrer comme des concepts part. La route atteint
sa destination comme elle atteint nimporte quelle autre position. Lavion doit suivre
la route, mais est-ce que a veut dire quil peut voler aussi haut ou aussi bas quil
veut ?
Expert : Non. Laltitude quun appareil doit avoir un moment donn est aussi tablie
dans le plan de vol.
Dveloppeur : Plan de vol ? Quest-ce que cest ?
Expert : Avant de quitter laroport, les pilotes reoivent un plan de vol dtaill qui
comprend toutes sortes dinformation sur le vol : la route, laltitude de croisire, la
vitesse de croisire, le type dappareil, et mme des informations sur les membres de
lquipage.
Dveloppeur : Hmm, le plan de vol ma lair assez important. On va linclure dans le
modle.
21
Dveloppeur : Voil qui est mieux. Maintenant que je le vois, je ralise quelque
chose. Quand on surveille le trafic arien, en fait on ne sintresse pas aux avions euxmmes, sils sont blancs ou bleus, ou si cest des Boeing ou des Airbus. On sintresse
leur vol. Cest a quon trace et quon mesure, en ralit. Je pense quon devrait
changer le modle un petit peu pour le rendre plus prcis.
Remarquez comment cette quipe, en parlant du domaine de la surveillance du trafic
arien autour de son modle naissant, est lentement en train de crer un langage
constitu des mots en gras. Notez aussi la manire dont ce langage change le modle !
Cependant, dans la vie relle ce dialogue est beaucoup plus bavard, et les gens parlent
trs souvent des choses indirectement, entrent trop dans les dtails, ou choisissent de
mauvais concepts ; ceci peut rendre la formation du langage trs difficile. Pour
commencer attaquer ce problme, tous les membres de lquipe devraient tre
conscients du besoin de crer un langage commun et on devrait leur rappeler de rester
concentrs sur lessentiel, et dutiliser le langage chaque fois que cest ncessaire.
Nous devrions utiliser notre jargon aussi peu que possible pendant ce genre de sance,
et on devrait se servir du Langage omniprsent car il nous aide communiquer
clairement et prcisment.
22
23
Bien que le comportement exprim par une mthode soit clair, le nom de la mthode
est-il aussi clair que son corps ? Les assertions dun test parlent delles-mmes, mais
quen est-il du nom des variables et de la structure gnrale du code ? Donnent-ils
haut et fort une version intgrale des faits ? Du code qui fonctionnellement fait ce quil
y a faire, nexprime pas forcment ce quil y a exprimer. Ecrire un modle en code
est trs difficile.
Il y a dautres faons de communiquer lors de la conception. Ce nest pas lobjectif de
ce livre de les prsenter toutes. Une chose est nanmoins claire : lquipe de
conception, compose darchitectes logiciels, de dveloppeurs et dexperts du
domaine, a besoin dun langage qui unifie leurs actions, et les aide crer un modle
et lexprimer dans du code.
25
3
Conception dirige par le Modle
Les chapitres prcdents soulignaient limportance dune approche du dveloppement
logiciel centre sur le domaine mtier. Nous avons dit quil tait fondamentalement
important de crer un modle profondment enracin dans le domaine, et qui reflte
les concepts essentiels du domaine avec une grande prcision. Le Langage
omniprsent devrait tre pratiqu pleinement tout au long du processus de
modlisation de manire faciliter la communication entre les spcialistes logiciels et
les experts du domaine, et dcouvrir les concepts cls du domaine qui devront tre
utiliss dans le modle. Lobjectif de ce processus de modlisation est de crer un bon
modle. Ltape suivante est limplmentation du modle en code. Cest une phase
tout aussi importante du processus de dveloppement logiciel. Si vous avez cr un
excellent modle mais que vous chouez le transfrer correctement dans le code, il
en rsultera en un logiciel de qualit discutable.
Il arrive que les analystes logiciels travaillent avec les experts du domaine mtier
pendant des mois, dcouvrent les lments fondamentaux du domaine, mettent en
lumire leurs relations, et crent un modle correct, qui capture le domaine de faon
exacte. Puis le modle est pass aux dveloppeurs. Ce qui peut se produire, cest que
les dveloppeurs regardent le modle et dcouvrent que certains des concepts ou
relations qui sy trouvent ne peuvent pas tre correctement exprims par du code. Ils
utilisent donc le modle original comme source dinspiration, mais ils crent leur
propre conception qui emprunte des ides du modle, et y ajoutent certaines de leurs
propres ides. Le processus de dveloppement se poursuit, et davantage de classes sont
ajoutes au code, creusant lcart entre le modle dorigine et limplmentation finale.
On nest plus assur davoir le bon rsultat la fin. Il se peut que de bons
dveloppeurs mettent sur pied un produit qui marche, mais rsistera-t-il lpreuve du
temps ? Sera-t-il facilement extensible ? Sera-t-il aisment maintenable ?
Tout domaine peut tre exprim travers de nombreux modles, et tout modle peut se
traduire de diverses manires dans le code. A chaque problme particulier il peut y
26
avoir plus dune solution. Laquelle choisir ? Avoir un modle analytiquement correct
ne signifie pas quil puisse tre directement exprim en code. A ce stade, la question
principale est la suivante : comment allons-nous aborder la transition du modle vers
le code ?
Parmi les techniques de conception parfois prconises, il y a ce quon appelle le
modle danalyse, qui est vu comme tant spar du design du code et gnralement
fait par des personnes diffrentes. Le modle danalyse est le produit de lanalyse du
domaine mtier, il se traduit par un modle qui ne prend pas en compte le logiciel
utilis dans limplmentation. On se sert de ce genre de modle pour comprendre le
domaine. Un certain niveau de connaissance est bti, et le modle rsultant peut tre
analytiquement correct. Le logiciel nest pas pris en compte cette tape car on le
considre comme un facteur de confusion. Ce modle parvient ensuite aux
dveloppeurs qui sont censs faire la conception. Comme le modle na pas t
construit avec des principes de conception en tte, il ne servira probablement pas bien
cet objectif. Les dveloppeurs devront ladapter, ou crer une conception spare. Et il
cesse dy avoir un mappage entre le modle et le code. Rsultat, les modles danalyse
sont rapidement abandonns aprs quon ait commenc coder.
Un des principaux problmes de cette approche est que les analystes ne peuvent pas
prvoir certains dfauts de leur modle, ni toutes les subtilits du domaine. Il arrive
que les analystes soient alls trop dans les dtails de certains composants du modle, et
nen aient pas assez prcis dautres. On dcouvre des dtails trs importants pendant
le processus de conception et dimplmentation. Il peut savrer quun modle fidle
au domaine ait de srieux problmes avec la persistance des objets, ou un
comportement inacceptable en termes de performances. Les dveloppeurs seront
obligs de prendre des dcisions par eux-mmes, et apporteront des modifications la
conception pour rsoudre un problme rel qui navait pas t pris en compte lorsque
le modle avait t cr. Ils produisent une conception qui sloigne du modle, le
rendant moins pertinent.
Si les analystes travaillent indpendamment, ils vont finalement crer un modle.
Quand ce modle est transmis aux concepteurs, une partie de la connaissance du
domaine et du modle dtenue par les analystes est perdue. Mme si on peut exprimer
le modle travers des diagrammes et des documents crits, il y a des chances pour
que les concepteurs ne saisissent pas tout le sens du modle, les relations entre certains
objets, ou leur comportement. Il y a des dtails dun modle qui ne sexpriment pas
facilement sous forme de diagramme, et ne peuvent pas tre prsents dans leur
intgralit mme dans des documents crits. Il ne sera pas facile pour les dveloppeurs
de les saisir. Dans certains cas ils feront des suppositions sur le comportement voulu,
et il est possible quils fassent les mauvaises, dbouchant sur un fonctionnement
incorrect du programme.
27
Les analystes tiennent leurs propres runions fermes o lon dbat de beaucoup de
choses autour du domaine, et o il y a beaucoup de partage de connaissance. Ils crent
un modle cens contenir toute linformation sous forme condense, et les
dveloppeurs doivent en assimiler lintgralit en lisant les documents quon leur
donne. Ce serait bien plus productif si les dveloppeurs pouvaient se joindre aux
runions des analystes et ainsi accder une vue claire, complte du domaine et du
modle avant de commencer concevoir le code.
Une meilleure approche est de lier troitement modlisation du domaine et conception.
Le modle devrait tre construit en gardant un il sur les considrations logicielles et
conceptuelles. On devrait intgrer les dveloppeurs dans le processus de modlisation.
Lide importante est de choisir un modle qui puisse tre exprim convenablement
dans du logiciel, pour que le processus de conception soit direct et bas sur le modle.
Le fait de coupler troitement le code un modle sous-jacent donne du sens au code
et rend le modle pertinent.
Impliquer les dveloppeurs permet davoir du feedback. Cela permet de sassurer que
le modle peut tre implment en logiciel. Si quelque chose ne va pas, le problme
est identifi un stade prcoce, et on peut facilement le corriger.
Ceux qui crivent le code devraient trs bien connaitre le modle, et se sentir
responsables de son intgrit. Ils devraient raliser quun changement dans le code
implique un changement dans le modle ; sans quoi ils refactoreront le code jusquau
point o il aura cess dexprimer le modle original. Si lanalyste est dissoci du
processus dimplmentation, il perdra rapidement toute proccupation concernant les
limites introduites par le dveloppement. Le rsultat de cela sera un modle qui nest
pas pragmatique.
Toute personne technique qui contribue llaboration du modle doit passer du temps
manipuler le code, quel que soit le rle premier quil ou elle joue dans le projet.
Toute personne ayant la responsabilit de modifier du code doit apprendre exprimer
un modle travers le code. Chaque dveloppeur doit tre impliqu, un niveau ou un
autre, dans la discussion autour du modle et tre en contact avec les experts du
domaine. Ceux qui contribuent de manire non technique doivent engager
consciemment, avec ceux qui manipulent le code, un change dynamique dides sur
le modle travers le Langage omniprsent.
Si on ne peut pas faire la correspondance entre la conception, ou une partie centrale de
celle-ci, et le modle du domaine, ce modle naura que peu de valeur, et la justesse du
logiciel sera suspecte. Qui plus est, les mappages complexes entre modles et
fonctions conceptuelles seront difficiles comprendre, et, en pratique, impossibles
maintenir lorsque la conception changera. Un foss mortel souvrira entre lanalyse et
28
la conception si bien que le discernement quon gagnera pratiquer lune des deux
activits ne nourrira pas lautre.
Concevez toute portion du systme logiciel de telle sorte quelle reflte le modle du
domaine de manire trs littrale, de cette manire le mappage sera vident. Revisitez
ensuite le modle et modifiez-le pour quil puisse tre implmentable plus
naturellement dans le logiciel, mme si votre but reste une reprsentation fine du
domaine. Exigez un modle unique qui serve bien ces deux objectifs, en plus de
supporter un Langage omniprsent fluide.
Puisez dans le modle la terminologie utiliser pour la conception et laffectation des
responsabilits de base. Le code devient une expression du modle, donc il se peut
quun changement apport au code se traduise en un changement du modle. Son effet
doit se propager en consquence travers le reste des activits du projet.
Lier troitement limplmentation un modle ncessite gnralement des langages et
outils de dveloppement qui supportent un paradigme de modlisation, comme par
exemple la programmation oriente objet.
La programmation oriente objet convient bien limplmentation de modle car ils
sont tous deux bass sur le mme paradigme. La programmation oriente objet prvoit
des classes dobjets et leurs associations, des instances dobjets, et lenvoi de messages
entre eux. Les langages de POO rendent possible la cration de mappages directs entre
les objets du modle avec leurs relations, et leurs quivalents en programmation.
Les langages procduraux offrent un support limit de la conception dirige par le
Modle. Ces langages ne proposent pas les briques ncessaires pour implmenter les
composants-cls dun modle. Certains disent quon peut faire de la POO avec un
langage procdural comme le C, et en effet, une partie des fonctionnalits peuvent tre
reproduites de cette faon. Les objets peuvent tre simuls par des structures de
donnes. Ce genre de structure ne contient pas le comportement de lobjet, il faut le
rajouter sparment dans des fonctions. La signification de telles donnes existe
seulement dans lesprit du dveloppeur, car le code lui-mme nest pas explicite. Un
programme crit dans un langage procdural est gnralement peru comme un
ensemble de fonctions, lune appelant lautre, qui travaillent ensemble pour atteindre
un rsultat donn. Un programme comme cela est incapable dencapsuler facilement
des connexions conceptuelles, ce qui rend le mappage entre le domaine et le code
difficile raliser.
Certains domaines spcifiques, comme les mathmatiques, sont facilement
modlisables et implmentables en programmation procdurale, car bien des thories
mathmatiques se traitent facilement en utilisant des appels de fonctions et des
structures de donnes, en effet il sagit avant tout de calculs. Il y a des domaines plus
29
complexes qui ne sont pas juste une suite de concepts abstraits impliquant des calculs,
et ne peuvent pas tre rduits un jeu dalgorithmes, cest pourquoi les langages
procduraux sont bien en peine dexprimer ces modles. Pour cette raison, la
programmation procdurale nest pas recommande en conception dirige par le
modle.
Larchitecture en couches
30
Lorsquon cre une application logicielle, une grande part de lapplication nest pas
relie directement au domaine, mais fait partie de linfrastructure ou sert le logiciel luimme. Il peut arriver, et cest justifi, que la partie domaine dune application soit
assez rduite compare au reste, puisquune application typique contient beaucoup de
code li laccs la base de donnes, laccs aux fichiers ou au rseau, aux
interfaces utilisateur, etc.
Dans un programme orient objet, le code de lIHM, de la base de donnes, et dautres
modules de support se retrouve souvent directement crit dans les objets mtier. Une
partie de la logique mtier est quant elle embarque dans le comportement des
composants dIHM et des scripts de base de donnes. Cela arrive parfois car cest la
faon la plus simple de faire marcher les choses rapidement.
Cependant, quand du code relatif au domaine est mlang aux autres couches, il
devient trs difficile de garder un il dessus et de sen souvenir. Des changements
superficiels dans lIHM peuvent en ralit modifier la logique mtier. Il se peut que
changer une rgle mtier exige une fouille mticuleuse dans code de lIHM, dans code
de la base de donnes, ou dautres lments du programme. Implmenter des objets
orients modle cohrents devient difficilement praticable. Les tests automatiss
deviennent peu commodes. Avec toute la technologie et toute la logique incluse dans
chaque activit, on doit garder un programme trs simple ou il devient impossible
comprendre.
Pour cette raison, vous devez partitionner un programme complexe en COUCHES.
Imaginez une conception au sein de chaque COUCHE qui soit cohrente et ne dpende
que des couches en-dessous. Suivez les modles darchitecture standard pour fournir
31
Couche application
Couche domaine
Couche infrastructure
Il est important de scinder une application en couches spares, et dtablir des rgles
dinteraction entre elles. Si le code nest pas clairement spar en couches, il deviendra
vite si enchevtr quil sera trs difficile de grer les changements. Une simple
modification dans une section du code pourra avoir des rsultats inattendus et
indsirables dans dautres sections. La couche domaine devrait se concentrer sur les
enjeux du cur du domaine. Elle ne devrait pas tre implique dans des activits
dinfrastructure. LIHM ne devrait tre troitement lie ni la logique mtier, ni aux
tches qui incombent normalement la couche infrastructure. Une couche application
est ncessaire dans beaucoup de cas : il faut quil y ait un gestionnaire au-dessus de la
logique mtier qui supervise et coordonne lactivit densemble de lapplication.
Par exemple, une interaction typique entre application, domaine et infrastructure
pourrait ressembler ceci : lutilisateur veut rserver une route pour un vol, et
32
Les Entits
Il y a une catgorie dobjets dont lidentit semble rester la mme au fil des tats du
logiciel. Chez ces objets, ce ne sont pas les attributs qui comptent, mais une ligne de
continuit et didentit qui stend sur la dure de vie dun systme et peut sallonger
au-del. Ces objets sont appels Entits.
Les langages de POO conservent des instances dobjets en mmoire, et ils associent
une rfrence ou une adresse mmoire chaque objet. Cette rfrence est unique un
objet un instant donn, mais il ny a aucune garantie quelle le reste indfiniment. En
fait, cest plutt le contraire. Les objets sont constamment enlevs et remis dans la
mmoire, ils sont srialiss et envoys travers le rseau pour tre recrs lautre
bout, ou ils sont dtruits. Cette rfrence, qui fait office didentit pour
lenvironnement dexcution du programme, nest pas lidentit dont nous parlons. Si
une classe porte une information sur la mto, comme la temprature, il est tout fait
possible davoir deux instances distinctes de cette classe qui contiennent toutes deux la
mme valeur. Les objets sont parfaitement gaux et interchangeables, mais ils ont des
rfrences diffrentes. Ce ne sont pas des entits.
Si nous devions implmenter le concept dune personne utilisant un programme
logiciel, nous crerions probablement une classe Personne avec une srie dattributs :
nom, date de naissance, lieu de naissance, etc. Est-ce quun de ces attributs constitue
lidentit de la personne ? Le nom ne peut pas tre lidentit parce quil peut y avoir
dautres gens qui sappellent pareil. On ne pourrait pas faire la distinction entre deux
personnes homonymes, si on devait seulement prendre en compte leur nom. Nous ne
pouvons pas non plus utiliser la date de naissance, parce quil y a beaucoup de gens
ns le mme jour. Il en va de mme pour lieu de naissance. Un objet doit se distinguer
des autres mme sils peuvent avoir les mmes attributs. Une confusion didentit peut
conduire une corruption des donnes.
Considrons lexemple dun systme de comptes bancaires. Chaque compte a son
propre numro. Un compte peut tre prcisment identifi par son numro. Ce numro
reste inchang tout au long de la vie du systme, et assure la continuit. Le numro de
compte peut exister en tant quobjet en mmoire, ou il peut tre dtruit de la mmoire
33
et envoy la base de donnes. Il peut aussi tre archiv quand le compte est ferm,
mais il existe toujours quelque part du moment quon a un intrt le garder sous le
coude. Peu importe la reprsentation qui en est faite, le numro reste le mme.
Donc, implmenter des entits dans le logiciel revient crer de lidentit. Pour une
personne a peut tre une combinaison dattributs : nom, date de naissance, lieu de
naissance, nom des parents et adresse actuelle. Le numro de scurit sociale est aussi
utilis aux Etats-Unis pour crer lidentit. Pour un compte bancaire, le numro de
compte semble suffire. Gnralement, lidentit est un attribut de lobjet, une
combinaison dattributs, un attribut spcialement cr pour prserver et exprimer
lidentit, ou mme un comportement. Il est important que deux objets avec des
identits diffrentes soient facilement distingus par le systme, et que deux objets de
mme identit soient considrs comme les mmes. Si cette condition nest pas
satisfaite, alors le systme entier peut devenir corrompu.
Il y a diffrentes manires de crer une identit unique pour chaque objet. LID peut
tre gnr automatiquement par un module, et utilis en interne dans le logiciel sans
tre rendu visible pour lutilisateur. Ca peut tre une cl primaire dans une table de la
base de donnes, qui est certifie unique dans la base. Lorsque lobjet est pris dans la
base, son ID est rcupr et recr en mmoire. LID peut aussi tre cr par
lutilisateur comme cest le cas avec les codes associs aux aroports. Chaque aroport
a un identifiant chane de caractres unique qui est reconnu internationalement et
utilis par les agences de voyages du monde entier pour identifier les aroports dans la
programmation de leurs voyages. Une autre solution est dutiliser les attributs de
lobjet pour crer lID, et quand a ne suffit pas, un autre attribut peut tre ajout pour
aider identifier lobjet en question.
Lorsquun objet se distingue par son identit plutt que par ses attributs, faites de cela
un lment primordial de sa dfinition dans le modle. Gardez une dfinition de la
classe simple et focalise sur la continuit du cycle de vie et lidentit. Dfinissez une
faon de distinguer chaque objet quelle que soit sa forme ou son historique. Restez
vigilant par rapport aux spcifications qui demandent retrouver des objets par leurs
attributs. Dfinissez une opration qui garantit la production dun rsultat unique pour
chaque objet, si possible en y rattachant un symbole qui est garanti unique. Ce moyen
didentification peut venir de lextrieur, ou a peut tre un identifiant arbitraire cr
par et pour le systme, mais il doit correspondre aux distinctions didentit dans le
modle. Le modle doit dfinir ce que signifie tre la mme chose .
Les entits sont des objets importants dun modle du domaine, et elles devraient tre
examines ds le dbut du processus de modlisation. Il est aussi important de
dterminer si un objet doit tre une entit ou non, cest ce dont il est question dans le
pattern suivant.
34
Les Objets-Valeurs
Nous avons parl des entits et de limportance de les reconnaitre tt dans la phase de
modlisation. Les entits sont des objets ncessaires dans un modle du domaine.
Devons-nous faire de tous les objets des entits ? Chaque objet doit-il avoir une
identit ?
Il pourrait tre tentant de faire de tous les objets des entits. Les entits peuvent tre
suivies la trace. Mais crer et tracer lidentit a un cot. On doit sassurer que chaque
instance a son identit unique, et tiqueter les identits nest pas simple. Dcider ce qui
constitue une identit demande une rflexion longue et minutieuse, car une mauvaise
dcision mnerait des objets de mme identit, ce quon ne souhaite pas. Il y a aussi
des rpercussions sur les performances dans le fait de faire de tous les objets des
entits. Il faut quil y ait une instance pour chaque objet. Si Client est un objet entit,
alors une instance de cet objet, qui reprsente un client particulier dune banque, ne
peut pas tre rutilise pour des oprations sur des comptes correspondant dautres
clients. La consquence est quune telle instance doit tre cre pour chaque client.
Cela peut avoir comme rsultat une dgradation des performances du systme
lorsquon a affaire des milliers dinstances.
Considrons lexemple dune application de dessin. On prsente lutilisateur un
canevas, et il peut y dessiner tous les points et lignes de lpaisseur, du style et de la
couleur quil souhaite. Il est utile de crer une classe dobjets nomme Point, et le
programme pourrait crer une instance de cette classe pour chaque point sur le
canevas. Un point comme celui-l contiendrait deux attributs associs ses
coordonnes sur lcran ou dans le canevas. Est-il ncessaire de considrer chaque
point comme ayant une identit ? Est-ce quil possde une continuit ? Il semble que la
seule chose qui compte chez un tel objet, ce sont ses coordonnes.
Il y a des cas o on a purement besoin de stocker des attributs dun lment du
domaine. Ce qui nous intresse nest pas de savoir de quel objet il sagit, mais quels
attributs il a. Un objet qui est utilis pour dcrire certains aspects dun domaine et qui
na pas didentit, est appel Objet-Valeur.
Il est ncessaire de distinguer les Objets Entits des Objets-Valeurs. Ca ne sert rien
de faire de tous les objets des entits juste pour des raisons duniformit. En fait, il est
plutt recommand de choisir comme entits seulement les objets qui sont conformes
la dfinition dune entit. Et de faire du reste des objets des Objets-Valeurs. (Nous
prsenterons un autre type dobjet dans la section suivante, mais supposons pour
linstant que nous avons seulement des objets entits et des objets-valeurs.) Ca va
simplifier la conception, et il y aura dautres consquences positives.
35
Nayant pas didentit, les Objets-Valeurs peuvent facilement tre crs et jets.
Personne na se soucier de leur crer une identit, et le garbage collector rgle son
compte lobjet quand il nest plus rfrenc par aucun autre objet. Ca simplifie
beaucoup le design.
Il est fortement recommand que les objets-valeurs soient immuables. Ils sont crs
laide dun constructeur, et jamais modifis au cours de leur vie. Lorsque vous voulez
une valeur diffrente pour lobjet, vous en crez tout simplement un autre. Ceci a des
consquences importantes sur la conception. Etant immuables, et nayant pas
didentit, les Objets-Valeurs peuvent tre partags. Ca peut savrer obligatoire dans
certains designs. Les objets immuables sont partageables, avec dimportantes
retombes en termes de performances. Ils ont aussi un caractre dintgrit, au sens
intgrit des donnes. Imaginez ce que cela voudrait dire de partager un objet qui nest
pas immuable. Un systme de rservation de voyages en avion pourrait crer des
objets pour chaque vol. Un des attributs pourrait tre le code du vol. Un client rserve
un vol pour une destination donne. Un autre client veut rserver sur le mme vol. Le
systme choisit de rutiliser lobjet qui comporte le code du vol, parce quil sagit du
mme vol. Entretemps, le client change davis, et choisit de prendre un vol diffrent.
Le systme change le code du vol car il nest pas immuable. Rsultat, le code du vol
du premier client change aussi.
Il y a une rgle dor : si les Objets-Valeurs sont partageables, ils doivent tre
immuables. Les Objets-Valeurs devraient garder une certaine minceur et une certaine
simplicit. Lorsquun Objet-Valeur est demand par un tiers, il peut simplement tre
pass par valeur, ou on peut en crer une copie et lui donner. Faire une copie dun
Objet-Valeur est simple, et gnralement sans aucune consquence. Sil ny a pas
didentit, vous pouvez faire autant de copies que vous voulez, et toutes les dtruire si
ncessaire.
36
Les Services
Quand on analyse le domaine et quon essaye de dterminer les principaux objets qui
le composent, on dcouvre que certains aspects du domaine ne se transposent pas
facilement en objets. On considre de manire gnrale que les objets ont des attributs,
un tat interne quils grent, et quils exposent un comportement. Lorsquon labore le
Langage omniprsent, les concepts cls du domaine sont introduits dans le langage, et
les noms de ce dernier sont facilement convertibles en objets. Les verbes du langage,
associs aux noms correspondants, viennent former une partie du comportement de ces
objets. Mais il y a certaines actions dans le domaine, certains verbes, qui ne semblent
appartenir aucun objet. Ils reprsentent un comportement important du domaine, ils
ne peuvent donc tre ngligs ou simplement incorpors dans des Entits ou des
Objets-Valeurs. Ajouter un tel comportement un objet le corromprait, le ferait
37
incarner une fonctionnalit qui ne lui appartient pas. Nanmoins, utilisant un langage
orient objet, nous sommes obligs demployer un objet cet effet. Il ne peut pas
simplement y avoir une fonction spare, toute seule. Elle doit tre rattache un
objet. Souvent, ce genre de comportement fonctionne travers plusieurs objets,
potentiellement de classes diffrentes. Par exemple, transfrer de largent dun compte
un autre : cette fonction devrait-elle se trouver dans le compte qui envoie ou dans le
compte qui reoit ? Lun et lautre semblent tout autant mal placs.
Lorsque ce genre de comportement est identifi dans le domaine, la meilleure mthode
est de le dclarer en tant que Service. Un tel objet na pas dtat interne, et son objectif
est simplement de fournir de la fonctionnalit au domaine. Lassistance fournie par un
Service peut tre non ngligeable, et un service peut regrouper des fonctionnalits
connexes qui servent aux Entits et aux Objets-Valeurs. Cest beaucoup mieux de
dclarer le Service explicitement, parce que cela cre une distinction claire dans le
domaine, a encapsule un concept. Mettre ce genre de fonctionnalit dans une Entit
ou un Objet-Valeur engendre de la confusion, car ce que ces objets reprsentent
napparaitra pas clairement.
Les services agissent comme des interfaces qui fournissent des oprations. Les
services sont courants dans les frameworks techniques, mais ils peuvent aussi tre
utiliss dans la couche domaine. Lintrt dun Service ne rside pas dans lobjet qui
rend le service, il est plutt li aux objets sur ou pour le compte desquels les oprations
sont effectues. Par consquent, il nest pas inhabituel quun Service devienne le point
de connexion de beaucoup dobjets. Cest une des raisons pour lesquelles un
comportement qui appartient naturellement un Service ne devrait pas tre inclus dans
les objets du domaine. Si on intgre une telle fonctionnalit dans les objets du
domaine, un rseau dassociations dense se cre entre eux et les objets bnficiaires
des oprations. Un degr lev de couplage entre de nombreux objets est le signe dun
pitre design parce que a rend le code difficile lire et comprendre, et, plus
important encore, a le rend difficile changer.
Un Service ne doit pas remplacer une opration qui appartient normalement aux objets
du domaine. On ne devrait pas crer un Service pour chaque opration dont on a
besoin. Mais lorsquil ressort quune telle opration est un concept important du
domaine, un Service doit tre cr pour a. Un service compte 3 caractristiques :
1. Lopration excute par le Service fait rfrence un concept du domaine qui
nappartient pas naturellement une Entit ou un Objet-Valeur.
2. Lopration effectue fait rfrence dautres objets du domaine.
3. Lopration na pas dtat.
38
cration et du retour du rapport. Puisque les rapports sont bass sur des gabarits, on
pourrait crer un Service, dont le but serait dobtenir le gabarit qui correspond un
reportID. Ce gabarit est stock dans un fichier ou en base de donnes. Lobjet Rapport
lui-mme nest pas lendroit appropri pour mettre une telle opration. Elle
nappartient pas lobjet Gabarit non plus. Donc on cre un Service part dont
lobjectif est de rcuprer le gabarit dun rapport en se basant sur lID du rapport. Ce
serait un service situ dans la couche du domaine. Il se servirait de linfrastructure
fichier pour aller chercher le gabarit sur le disque.
Les Modules
Dans une application vaste et complexe, le modle a tendance devenir de plus en
plus gros. Le modle atteint un point ou il est difficile de parler de lui dans sa
globalit, et o il devient compliqu de comprendre les relations et interactions entre
ses diffrentes parties. Cest la raison pour laquelle il est ncessaire dorganiser le
modle en modules. Les modules sont utiliss comme mthode dorganisation des
concepts et tches connexes en vue de rduire la complexit.
Les modules sont largement utiliss dans la plupart des projets. Il est plus facile de
saisir le tableau densemble dun gros modle si vous regardez les modules quil
contient, puis les relations entre ces modules. Une fois quon a compris linteraction
entre les modules, on peut commencer sintresser aux dtails lintrieur dun
module. Cest une manire simple et efficace de grer la complexit.
Une autre raison dutiliser des modules est lie la qualit du code. Il est largement
reconnu que le code logiciel doit avoir un fort niveau de cohsion et un faible niveau
de couplage. Mme si la cohsion commence lchelle de la classe et de la mthode,
elle peut tre applique lchelle du module. Il est recommand de regrouper les
classes fortement lies dans des modules pour fournir le maximum de cohsion
possible. Il y a plusieurs types de cohsion. Deux des plus rpandues sont la cohsion
communicationnelle et la cohsion fonctionnelle. La cohsion communicationnelle est
effective lorsque des parties du module oprent sur les mmes donnes. Ca a du sens
de les regrouper, car il existe une forte relation entre elles. La cohsion fonctionnelle
est atteinte quand toutes les parties du module travaillent de concert pour raliser une
tche bien dfinie. Elle est considre comme la meilleure forme de cohsion.
Utiliser des modules dans la conception est une faon de renforcer la cohsion et de
diminuer le couplage. Les modules devraient tre constitus dlments qui vont de
pair fonctionnellement ou logiquement, ce qui assure la cohsion. Les modules
devraient avoir des interfaces bien dfinies auxquelles accdent dautres modules. Au
lieu dappeler trois objets dun module, il est mieux daccder une interface, car cela
40
Les Agrgats
Les trois derniers patterns de ce chapitre vont traiter dun autre dfi de modlisation,
un dfi li au cycle de vie des objets du domaine. Les objets du domaine passent par
une srie dtats au cours de leur vie. Ils sont crs, placs en mmoire et utiliss dans
des traitements, puis ils sont dtruits. Dans certains cas ils sont sauvegards dans des
emplacements permanents, comme une base de donnes, o on peut les rcuprer un
peu plus tard, ou bien ils sont archivs. A un moment donn ils peuvent tre
compltement effacs du systme, y compris de la base et de larchive.
Grer le cycle de vie dun objet du domaine constitue un dfi en soi, et si ce nest pas
fait correctement, cela peut avoir un impact ngatif sur le modle du domaine. Nous
allons prsenter trois patterns qui nous aident rgler cela. Agrgat est un pattern de
domaine utilis pour dfinir lappartenance et les frontires des objets. Les Fabriques
41
et les Entrepts sont deux design patterns qui nous aident traiter la cration des
objets et leur stockage. Nous allons commencer par parler des Agrgats.
Un modle peut contenir un grand nombre dobjets du domaine. Aussi grande soit
lattention porte la conception, il arrive que de nombreux objets soient associs
entre eux, crant un rseau de relations complexe. Il y a plusieurs types dassociations.
Pour chaque association traversable du modle, il doit y avoir un mcanisme logiciel
correspondant qui la met en application. Les vritables associations entre objets du
domaine se retrouvent dans le code, et souvent mme dans la base de donnes. Une
relation un--un entre un client et le compte bancaire ouvert son nom est exprime
sous la forme dune rfrence entre deux objets, et engendre une relation entre deux
tables en base, celle qui contient les clients et celle qui contient les comptes.
Bien souvent, le dfi avec les modles nest pas de faire en sorte quils soient
suffisamment complets, mais de les rendre les plus simples et les plus comprhensibles
possible. La plupart du temps, il savre payant dliminer ou de simplifier des
relations du modle. A moins bien sr quelles ne reclent une comprhension
profonde du domaine.
Une association un--plusieurs est plus complexe car elle met en jeu de nombreux
objets qui deviennent lis. Cette relation peut tre simplifie en la transformant en une
association entre un objet et une collection dautres objets, bien que a ne soit pas
toujours possible.
Il existe des associations plusieurs--plusieurs et un grand nombre dentre elles sont
bidirectionnelles. Cela augmente beaucoup la complexit, rendant la gestion du cycle
de vie de ce genre dobjets assez difficile. Le nombre dassociations devrait tre rduit
autant que possible. En premier lieu, les associations qui ne sont pas essentielles pour
le modle devraient tre retires. Il se peut quelles existent dans le domaine, mais
quelles ne soient pas ncessaires dans notre modle, donc on peut les enlever.
Deuximement, la multiplicit peut tre rduite en ajoutant une contrainte. Si
beaucoup dobjets satisfont une relation, cest possible quun seul puisse le faire si
on impose la bonne contrainte sur la relation. Troisimement, dans bien des cas les
associations bidirectionnelles peuvent tre transformes en associations
unidirectionnelles. Chaque voiture a un moteur, et chaque moteur a une voiture dans
laquelle il tourne. La relation est bidirectionnelle, mais elle peut facilement tre
simplifie en considrant que la voiture a un moteur, et pas linverse.
Aprs avoir rduit et simplifi les associations entre objets, il se peut quon ait encore
beaucoup de relations sur les bras. Un systme bancaire dtient et traite des donnes
client. Ces donnes comprennent les informations personnelles du client, comme le
nom, ladresse, les numros de tlphone, la description de lemploi, et des
informations sur le compte : numro de compte, solde, oprations effectues, etc.
42
43
objets de lagrgat, il est facile dassurer les invariants, car cest la racine qui le fait.
Ca serait beaucoup plus dur faire si des objets externes avaient un accs direct aux
objets internes et les modifiaient. Garantir les invariants dans cette circonstance
impliquerait de mettre la logique adquate dans des objets externes, ce qui nest pas
souhaitable.
La racine a la possibilit de passer des rfrences phmres dobjets internes des
objets externes, la condition que les objets externes ne conservent pas la rfrence
aprs que lopration soit finie. Une illustration simple de cela consiste passer des
copies dObjets Valeurs aux objets externes. Ce qui arrive ces objets nest pas
vraiment important, parce que a naffectera pas lintgrit de lagrgat de toute faon.
Si les objets dun Agrgat sont stocks en base de donnes, seule la racine devrait
pouvoir tre obtenue par des requtes. Ont devrait accder aux autres objets travers
des associations traversables.
Les objets lintrieur dun Agrgat doivent tre autoriss dtenir des rfrences
vers les racines dautres Agrgats.
LEntit racine a une identit globale, et elle est responsable du maintien des
invariants. Les Entits internes ont une identit locale.
Rassemblez les Entits et Objets Valeurs dans des Agrgats et dfinissez des frontires
autour de chacun. Dans chaque Agrgat, choisissez une Entit qui sera la racine, et
faites-lui contrler laccs aux objets situs lintrieur de la frontire. Vous ne devez
autoriser les objets externes dtenir des rfrences que vers la racine. Des rfrences
phmres vers des membres internes peuvent tre passes au-dehors uniquement dans
le cadre dune utilisation pour une opration ponctuelle. Puisque la racine contrle
laccs, elle ne peut pas tre prise de court par une modification inattendue des
lments internes. Grce cet arrangement, il devient pratique dassurer les invariants
des objets de lAgrgat et de lAgrgat dans sa globalit lors de tout changement
dtat.
Un exemple simple dAgrgation est prsent dans le diagramme qui suit. Le client est
la racine de lAgrgat, et tous les autres objets sont internes. Si on a besoin de
lAdresse, une copie de celle-ci peut tre passe aux objets externes.
44
Les Fabriques
Les Entits et les Agrgats peuvent parfois tre vastes et complexes trop complexes
pour tre crs dans le constructeur de lentit racine. En fait, essayer de construire un
agrgat complexe dans son constructeur serait entrer en contradiction avec la manire
dont a se passe souvent dans le domaine lui-mme, o des choses sont cres par
dautres choses (comme les composants lectroniques sont crs par des lignes
dassemblage). Ce serait comme demander une imprimante de se construire ellemme.
Lorsquun objet client veut crer un autre objet, il appelle son constructeur et lui passe
ventuellement des paramtres. Mais quand la construction de lobjet est un processus
laborieux, crer lobjet demande une grande connaissance de sa structure interne, des
relations entre les autres objets quil contient, et des rgles qui sy appliquent. En
dautres termes, chaque client de lobjet va devoir dtenir une connaissance spcifique
de lobjet construire. Ca rompt lencapsulation des objets du domaine et des
Agrgats. Si le client appartient la couche application, une partie de la couche
domaine a t dplace ailleurs, ce qui dtraque toute la conception. Dans la vie relle,
cest comme si on nous donnait du plastique, du caoutchouc, du mtal, du silicium et
quon construisait notre propre imprimante. Ce nest pas impossible faire, mais cela
en vaut-il rellement la peine ?
La cration dun objet a beau tre une opration importante en soi, les oprations
dassemblage complexes ne sont pas de la responsabilit des objets crateurs.
45
Combiner de telles responsabilits peut produire des designs disgracieux qui sont
difficiles comprendre.
Cest pourquoi il est ncessaire dintroduire un nouveau concept qui aide encapsuler
le processus de cration dun objet complexe. Cest ce quon appelle une Fabrique.
Les Fabriques sont utilises pour encapsuler la connaissance ncessaire la cration
des objets, et elles sont particulirement utiles pour crer des Agrgats. Quand la
racine dun Agrgat est cre, tous les objets contenus dans lAgrgat sont crs en
mme temps quelle, et tous les invariants sont appliqus.
Il est important que le processus de cration soit atomique. Si ce nest pas le cas, il y a
des chances pour que le processus soit moiti termin chez certains objets, les
laissant dans un tat indtermin. Cest encore plus vrai pour les Agrgats. Lorsquon
cre la racine, il est ncessaire de crer aussi tous les objets sujets des invariants.
Sinon, les invariants ne peuvent pas tre appliqus. Pour des Objets Valeurs
immuables, cela veut dire que tous les attributs sont initialiss dans un tat valide. Si
un objet ne peut pas tre cr correctement, une exception devrait tre leve, assurant
quon ne retourne pas une valeur invalide.
Pour cette raison, faites basculer la responsabilit de crer des instances dobjets
complexes et dAgrgats dans un objet spar, qui potentiellement na lui-mme
aucune responsabilit dans le modle du domaine mais fait tout de mme partie du
design du domaine. Fournissez une interface qui encapsule tout lassemblage
complexe et ne ncessite pas que le client rfrence les classes concrtes des objets
instancier. Crez les Agrgats entiers de faon unitaire, en appliquant leurs invariants.
On utilise plusieurs design patterns pour implmenter les Fabriques. Le livre Design
Patterns (Gamma et al.) les dcrit en dtail, et prsente entre autres ces deux
patterns : Mthode de fabrication, et Fabrique abstraite1. Nous nallons pas tenter de
prsenter ces patterns dun point de vue conception, mais dun point de vue
modlisation du domaine.
Une Mthode de fabrication est une mthode dun objet qui contient et masque la
connaissance ncessaire pour crer un autre objet. Cest trs utile lorsquun client veut
crer un objet qui appartient un Agrgat. La solution est dajouter une mthode la
racine dagrgat qui soccupe de crer lobjet, de mettre en uvre tous les invariants,
et de retourner une rfrence vers cet objet ou vers une copie de cet objet.
46
Le conteneur contient des composants qui sont dun certain type. Quand un tel
composant est cr, il est ncessaire quil appartienne automatiquement un
conteneur. Le client appelle la mthode creerComposant(Type t) du conteneur. Le
conteneur instancie un nouveau composant. La classe concrte du composant est
dtermine en se basant sur son type. Aprs sa cration, le composant est ajout la
collection de composants du conteneur, et une copie en est retourne au client.
Il y a des fois o la construction dun objet est soit plus complexe, soit elle implique la
cration dune srie dobjets. Par exemple : la cration dun Agrgat. Cacher les
besoins internes de cration dun Agrgat peut se faire dans un objet Fabrique spar
qui est ddi cette tche. Prenons lexemple dun module dun programme qui
calcule la route pouvant tre suivie par une voiture dun point de dpart une
destination, tant donn une srie de contraintes. Lutilisateur se connecte au site web
qui excute lapplication et spcifie une des contraintes suivantes : trajet le plus court,
trajet le plus rapide, trajet le moins cher. Les trajets crs peuvent tre annots avec
des informations utilisateur quil faut sauvegarder, pour quon puisse les retrouver plus
tard lorsque lutilisateur se connectera nouveau.
47
Le gnrateur dID de route est utilis pour crer une identit unique pour chaque
route, chose ncessaire pour une Entit.
Lorsquon cre une Fabrique, on est forc de violer lencapsulation dun objet, ce qui
doit tre fait avec prudence. A chaque fois que quelque chose change dans lobjet qui a
un impact sur les rgles de construction ou sur certains des invariants, nous devons
nous assurer que le code de la Fabrique est mis jour pour supporter les nouvelles
conditions. Les Fabriques sont profondment lies aux objets quelles crent. Ca peut
tre une faiblesse, mais a peut aussi tre une force. Un Agrgat contient une srie
dobjets troitement relis entre eux. La construction de la racine est associe la
cration des autres objets de lAgrgat, et il doit y avoir une logique pour constituer un
Agrgat. Cette logique nappartient pas naturellement un des objets, parce quelle
concerne la construction dautres objets. Il semble adapt dutiliser une classe
Fabrique spciale qui on confie la tche de crer lAgrgat tout entier, et qui
contiendra les rgles, les contraintes et les invariants devant tre appliqus pour que
lAgrgat soit valide. Les objets resteront simples et serviront leur propre but sans tre
gns par le fouillis dune logique de construction complexe.
Les Fabriques dEntits sont diffrentes des Fabriques dObjets Valeurs. Les Objets
Valeurs sont gnralement immuables, et tous les attributs ncessaires doivent tre
produits au moment de leur cration. Lorsque lobjet est cr, il doit tre valide et
finalis. Il ne changera pas. Les Entits ne sont pas immuables. Elles peuvent tre
changes plus tard en modifiant des attributs, en ajoutant que tous les invariants
doivent tre respects. Une autre diffrence vient du fait que les Entits ont besoin
dune identit alors que les Objets Valeurs, non.
48
Les Entrepts
Dans une conception dirige par le modle, les objets ont un cycle de vie qui
commence par leur cration et se termine avec leur suppression ou leur archivage. Un
constructeur ou une Fabrique se charge de la cration de lobjet. Tout lobjectif de
crer des objets est de pouvoir les utiliser. Dans un langage orient objet, on doit
possder une rfrence vers un objet pour tre capable de sen servir. Pour avoir cette
rfrence, le client doit soit crer lobjet, soit lobtenir dun autre, en traversant une
association existante. Par exemple, pour obtenir un Objet-Valeur dun Agrgat, le
client doit le demander la racine de lAgrgat. Lennui, cest que maintenant le client
a une rfrence vers la racine. Dans de grosses applications, a peut tre un problme
parce quon doit sassurer que le client a toujours une rfrence vers lobjet dont il a
besoin, ou vers un autre objet qui lui, a cette rfrence. Utiliser ce genre de rgle dans
la conception va forcer les objets conserver une srie de rfrences quils ne
garderaient probablement pas autrement. Cela augmente le couplage, crant une srie
dassociations dont on na pas vraiment besoin.
49
Utiliser un objet implique que lobjet ait dj t cr. Si lobjet est la racine dun
Agrgat, alors cest une Entit, et il y a des chances pour quelle soit stocke dans un
tat persistant dans une base de donnes ou une autre forme de stockage. Si cest un
Objet-Valeur, il peut tre obtenu auprs dune Entit en traversant une association,
mais il savre que bon nombre dobjets peuvent tre directement rcuprs dans une
base de donnes. Cela rsout le problme de lobtention de rfrences dobjets. Quand
un client veut utiliser un objet, il accde la base, y retrouve lobjet et sen sert. Cela
semble une solution simple et rapide, mais a a des impacts ngatifs sur le design.
Les bases de donnes font partie de linfrastructure. Une solution mdiocre serait que
le client connaisse les dtails requis pour accder une base. Par exemple, le client
devrait crer des requtes SQL pour rcuprer les donnes souhaites. La requte de
base de donnes retournerait un jeu denregistrements, exposant encore plus de ses
dtails internes. Quand beaucoup de clients doivent crer des objets directement depuis
la base de donnes, ce genre de code se retrouve parpill un peu partout dans le
domaine. A cet instant le modle du domaine est compromis. Il doit traiter de
nombreux dtails dinfrastructure au lieu de soccuper des concepts du domaine. Que
se passe-t-il si la dcision est prise de changer la base de donnes sous-jacente ? Tout
ce code dispers doit tre modifi pour quon puisse accder au nouvel emplacement
de stockage. Lorsque du code client accde une base directement, il est possible quil
restaure un objet interne un Agrgat. Cela rompt lencapsulation de lAgrgat, avec
des consquences inconnues.
Un client a besoin dun moyen concret dacqurir des rfrences vers des objets du
domaine prexistants. Si linfrastructure rend cela facile, il est probable que les
dveloppeurs du code client ajouteront plus dassociations traversables et embrouillent
le modle. Ou alors, il se peut quils utilisent des requtes pour puiser directement
dans la base les donnes exactes dont ils ont besoin, ou pour piocher quelques objets
spcifiques plutt que de naviguer partir des racines dagrgats. La logique du
domaine est dplace dans les requtes et le code client, et les Entits et Objets
Valeurs deviennent de simples conteneurs de donnes. La complexit technique brute
de limplmentation de linfrastructure daccs la base submerge rapidement le code
client, ce qui amne les dveloppeurs abtir la couche domaine, et rend le modle
obsolte. Leffet gnral est quon perd la focalisation sur le domaine et quon
compromet le design.
Pour cette raison, utilisez un Entrept, dont le but est dencapsuler toute la logique
ncessaire lobtention de rfrences dobjets. Les objets du domaine nauront pas
soccuper de linfrastructure de rcupration des rfrences aux autres objets du
domaine dont ils ont besoin. Ils iront simplement les chercher dans lEntrept et le
modle retrouvera sa clart et sa focalisation.
50
LEntrept est capable de conserver des rfrences vers des objets. Quand un objet est
cr, il peut tre sauvegard dans lEntrept, et y tre rcupr plus tard quand on
voudra lutiliser. Si le client demande un objet lEntrept, et que lEntrept ne la
pas, ce dernier peut aller le chercher dans lemplacement de stockage physique. Dans
tous les cas, lEntrept agit comme un endroit o sont emmagasins des objets
globalement accessibles.
LEntrept peut aussi comporter une Stratgie. Il peut accder un stockage persistant
ou un autre en fonction de la Stratgie prcise. Il se peut quil utilise diffrents
emplacements de stockage pour diffrents types dobjets. Cela a pour effet global de
dcoupler le modle du domaine du besoin de stocker des objets ou leurs rfrences et
de celui daccder linfrastructure de persistance sous-jacente.
Pour chaque type dobjet qui ncessite un accs global, crez un objet qui puisse
procurer lillusion dune collection en mmoire de tous les objets de ce type.
Organisez-en laccs travers une interface globale connue de tous. Fournissez des
mthodes pour ajouter et enlever des objets, qui encapsuleront les vritables insertions
et suppressions de donnes dans le stockage des donnes. Proposez des mthodes qui
slectionnent des objets en se basant sur des critres et qui retournent des objets ou
collections dobjets pleinement instancis dont les valeurs satisfont les critres ; ce
faisant, vous encapsulerez la technologie relle de stockage et de requtage.
Fournissez des Entrepts seulement pour les racines dagrgats qui ncessitent
rellement un accs direct. Conservez un client focalis sur le modle, en dlgant tout
stockage ou accs aux donnes aux Entrepts.
Un Entrept peut contenir des informations dtailles dont il se sert pour accder
linfrastructure, mais son interface devrait tre simple. Un Entrept doit avoir un jeu
de mthodes utilises pour rcuprer des objets. Le client appelle une de ces mthodes
51
et lui passe un ou plusieurs paramtres qui reprsentent les critres de slection utiliss
pour choisir un objet ou un ensemble dobjets correspondants. Une Entit peut
facilement tre demande en passant son identit. Dautres critres de slection
peuvent tre constitus dun ensemble dattributs de lobjet. LEntrept va comparer
tous les objets cet ensemble et retournera ceux qui satisfont aux critres. Linterface
de lEntrept pourrait aussi contenir des mthodes utilises pour effectuer des calculs
supplmentaires comme le nombre dobjets dun certain type.
On notera que limplmentation dun entrept peut tre troitement assimile de
linfrastructure, mais que linterface de lentrept est du pur modle du domaine.
Une autre option est de prciser des critres de slection sous forme de Spcification.
La Spcification permet de dfinir des critres plus complexes, comme dans lexemple
suivant :
52
Il y a une relation entre Fabrique et Entrept. Ce sont tous deux des patterns de
conception dirige par le modle, et ils nous aident tous les deux grer le cycle de vie
des objets du domaine. Tandis que la Fabrique est concerne par la cration dobjets,
lEntrept se charge des objets dj existants. LEntrept peut mettre en cache des
objets localement, mais trs souvent il a besoin de les rcuprer dans un lieu de
stockage persistant. Les objets sont soit crs en utilisant un constructeur, soit on les
passe une Fabrique pour quils y soient construits. Cest pour cette raison que
lEntrept peut tre vu comme une Fabrique, car il cre des objets. Ce nest pas une
cration ex nihilo, mais la reconstitution dun objet qui a exist. On ne doit pas
mlanger Entrept et Fabrique. La fabrique cre de nouveaux objets, tandis que
lEntrept retrouve des objets dj crs. Quand un nouvel objet doit tre ajout
53
Une autre faon de qualifier cela est de dire que les Fabriques sont purement
domaine alors que les Entrepts peuvent contenir des liens avec linfrastructure, par
exemple la base de donnes.
54
4
Refactorer pour une vision plus profonde
Refactorer en continu
55
quelle ntait. Sans ces outils, il peut tre trs difficile de refactorer. Ce genre de
refactoring concerne plus le code et sa qualit.
Il existe un autre type de refactoring, qui est li au domaine et son modle. Parfois on
a de nouvelles ides sur le domaine, quelque chose devient plus clair, ou on dcouvre
une relation entre deux lments. Tout ceci doit tre inclus dans la conception via du
refactoring. Il est trs important davoir un code expressif, facile lire et
comprendre. A la lecture du code, on devrait tre capable de dire ce quil fait, mais
aussi pourquoi il le fait. Cest cette seule condition que le code peut vritablement
capturer la substance du modle.
Le refactoring technique, celui bas sur des patterns, peut tre organis et structur. Un
refactoring pour une vision plus profonde ne peut pas seffectuer de la mme manire.
On ne peut pas crer des patterns pour a. La complexit et la varit des modles ne
nous offrent pas la possibilit daborder la modlisation de faon mcanique. Un bon
modle est le produit dune rflexion profonde, de la perspicacit, de lexprience, et
du flair.
Une des premires choses quon nous apprend sur la modlisation, cest de lire les
spcifications fonctionnelles et de chercher les noms et les verbes. Les noms sont
convertis en classes, tandis que les verbes deviennent des mthodes. Cest une
simplification, et cela mne un modle superficiel. Tous les modles manquent de
profondeur au dbut, et nous devrions les refactorer en vue dune comprhension
toujours plus fine.
La conception doit tre flexible. Un design rigide rsiste au refactoring. Du code qui
na pas t construit dans un esprit de flexibilit, cest du code avec lequel il est
difficile de travailler. A chaque besoin de changement, vous allez devoir vous battre
avec le code, et les choses refactorer prendront facilement beaucoup de temps.
Utiliser un ensemble prouv de blocs de construction de base ainsi quun langage
cohrent assainit dj leffort de dveloppement. Ca nous laisse avec le dfi de trouver
un modle incisif, un modle qui capture les proccupations subtiles des experts du
domaine et peut guider une conception pragmatique. Un modle qui se dbarrasse du
superficiel et capture lessentiel est un modle profond. Cela devrait mettre le logiciel
davantage au diapason du mode de pense des experts du domaine, et le rendre plus
rceptif aux besoins des utilisateurs.
Traditionnellement, le refactoring est dcrit en termes de transformations de code avec
des motivations techniques. Le refactoring peut aussi tre motiv par une avance
nouvelle dans le domaine et le raffinement correspondant du modle ou de son
expression dans le code.
56
Les modles du domaine sophistiqus sont rarement dvelopps autrement que par un
processus itratif de refactoring, qui suppose une implication troite des experts mtier
et des dveloppeurs intresss par lapprentissage du domaine.
Le refactoring se fait par petites tapes. Aussi, le rsultat est une srie de petites
amliorations. Il y a des fois ou de nombreux petits changements ajoutent trs peu de
valeur au design, et dautres o quelques changements font une grande diffrence.
Cest ce quon appelle une Avance majeure.
Au dbut, on a un modle superficiel et grossier. Ensuite nous le raffinons, lui et le
design, en nous basant sur une connaissance plus profonde du domaine, sur une
meilleure comprhension de ses enjeux. On y ajoute des abstractions. Puis la
conception est refactore. Chaque affinage ajoute de la clart au design. Cela cre
ensuite les conditions pour une Avance majeure.
Une Avance majeure implique souvent un changement dans la faon dont nous
pensons et voyons le modle. Cest une source de grand progrs dans le projet, mais
cela a aussi ses inconvnients. Une Avance majeure peut impliquer une grande
quantit de refactoring. Cela signifie du temps et des ressources, choses dont, semblet-il, nous manquons toujours. Cest galement risqu, car un vaste refactoring peut
introduire des changements dans le comportement de lapplication.
Pour raliser une Avance majeure, il nous faut rendre explicites les concepts
implicites. Quand on parle aux experts du domaine, on change beaucoup dides et de
connaissances. Certains concepts se frayent un chemin jusquau Langage omniprsent,
mais dautres passent inaperus dans un premier temps. Ce sont des concepts
implicites, utiliss pour expliquer dautres concepts dj prsents dans le modle.
Pendant le processus daffinage de la conception, quelques-uns de ces concepts
implicites attirent notre attention. On dcouvre que certains dentre eux jouent un rle
cl dans la conception. Cest ce moment-l que nous devrions rendre ces concepts
explicites. On devrait leur crer des classes et des relations. Quand a se produit, il se
peut quon ait la chance dtre face une Avance majeure.
Les concepts implicites ne devraient pas le rester. Si ce sont des concepts du domaine,
ils devraient tre prsents dans le modle et dans la conception. Comment les
reconnaitre ? La premire faon de dcouvrir des concepts implicites, cest dcouter
57
58
On peut ajouter des livres une tagre, mais on ne devrait jamais pouvoir en ajouter
plus que sa capacit. On peut voir a comme faisant partie du comportement de
lEtagre, comme dans le code Java qui suit.
public class Etagere {
private int capacite = 20;
private Collection contenu;
public void ajouter(Livre livre) {
if(contenu.size() + 1 <= capacite) {
contenu.add(livre);
} else {
throw new IllegalOperationException(
Ltagre a atteint sa limite.);
}
}
}
Nous pouvons refactorer le code en extrayant la contrainte dans une mthode spare.
public class Etagere {
private int capacite = 20;
private Collection contenu;
public void ajouter(Livre livre) {
if(espaceEstDisponible()) {
contenu.add(livre);
} else {
throw new IllegalOperationException(
Ltagre a atteint sa limite.);
}
}
private boolean espaceEstDisponible() {
return contenu.size() < capacite;
}
59
Placer la contrainte dans une mthode spare a lavantage de la rendre explicite. Cest
facile lire et tout le monde remarquera que la mthode ajouter() est sujette cette
contrainte. Il y aura aussi de la place pour une volution lorsquon voudra ajouter plus
de logique aux mthodes, si la contrainte devient plus complexe.
Les Processus sont gnralement exprims dans du code travers des procdures.
Nous nallons pas utiliser une approche procdurale, puisque nous utilisons un langage
orient objet ; il nous faut donc choisir un objet pour le processus, et y ajouter un
comportement. La meilleure manire dimplmenter les processus est dutiliser un
Service. Sil y a diffrentes manires de mener bien le processus, alors nous pouvons
encapsuler lalgorithme dans un objet et utiliser une Stratgie. Tous les processus ne
sont pas destins tre rendus explicites. Le bon moment pour implmenter
explicitement un processus, cest quand le Langage omniprsent le mentionne
expressment.
La dernire mthode pour rendre les concepts explicites dont nous traiterons ici est la
Spcification. Pour faire simple, on utilise une Spcification pour tester un objet afin
de voir sil satisfait certains critres.
La couche domaine contient des rgles mtier qui sappliquent aux Entits et aux
Objets Valeurs. Ces rgles sont classiquement intgres dans les objets auxquels elles
sappliquent. Certaines dentre elles sont juste un ensemble de questions dont la
rponse est oui ou non . Ce genre de rgle peut tre exprim par une srie
doprations logiques appliques sur des valeurs boolennes, et le rsultat final est
aussi un boolen. Un exemple de a, cest le test effectu sur un objet Client pour voir
sil est ligible un certain crdit. La rgle peut tre exprime sous forme de mthode
appele estEligible(), et rattache lobjet Client. Mais cette rgle nest pas une simple
mthode qui opre strictement sur des donnes du Client. Lvaluation de la rgle
implique de vrifier les rfrences du client, de voir sil a pay ses dettes dans le pass,
dexaminer sil a des soldes ngatifs, etc. Ces rgles mtier peuvent tre grosses et
complexes et faire gonfler lobjet au point quil ne serve plus son objectif dorigine. A
ce moment on pourrait tre tent de dplacer lintgralit de la rgle au niveau
application, car elle semble stendre au-del du niveau domaine. En fait, il est temps
de refactorer.
La rgle doit tre encapsule dans un objet spar qui devient la Spcification du
Client, et quon doit laisser dans la couche domaine. Le nouvel objet va contenir une
srie de mthodes boolennes qui testent si un objet Client particulier est ligible pour
un crdit ou pas. Chaque mthode joue le rle dun petit test, et toutes les mthodes
combines donnent la rponse la question dorigine. Si la rgle mtier nest pas
60
comprise dans un unique objet Spcification, le code qui correspond finira parpill
dans bon nombre dobjets, ce qui le rendra incohrent.
La Spcification est utilise pour tester des objets pour voir sils rpondent un
besoin, ou sils sont prts remplir un objectif. On peut aussi sen servir pour
slectionner un objet particulier dans une collection, ou comme condition durant la
cration dun objet.
Souvent, il y a une Spcification spare pour vrifier que chaque rgle simple est
satisfaite, et ensuite on combine un certain nombre dentre elles dans une spcification
composite qui exprime la rgle complexe, comme ceci :
Client client =
entrepotClients.trouverClient(identiteClient);
Il est plus simple de tester des rgles lmentaires, et juste en regardant ce code, la
dfinition dun client ligible un remboursement devient vidente.
61
5
Prserver lintgrit du modle
Ce chapitre traite des gros projets qui ncessitent les efforts combins de multiples
quipes. On se retrouve face un nouvel ensemble de dfis lorsquon confie
plusieurs quipes, dans des conditions de management et de coordination diverses, la
tche de dvelopper un projet. Les projets dentreprise sont gnralement vastes, ils
emploient des technologies et des ressources varies. La conception de tels projets
devrait tout de mme tre base sur un modle du domaine, et on doit prendre les
mesures qui correspondent pour sassurer de la russite du projet.
Quand plusieurs quipes travaillent sur un projet, le dveloppement du code est fait en
parallle, chaque quipe se voyant assigner une partie spcifique du modle. Ces
parties ne sont pas indpendantes, mais plus ou moins interconnectes. On part dun
seul gros modle, et tout le monde reoit une partie de celui-ci implmenter.
Supposons quune quipe a cr un module, et le rend disponible lusage des autres
quipes. Un dveloppeur dune autre quipe commence utiliser le module, et
dcouvre quil manque ce dernier une fonctionnalit requise par son propre module.
Il ajoute cette fonctionnalit et archive le code pour quil puisse tre utilis par tous.
Ce quil na peut-tre pas ralis, cest que a constitue en ralit un changement du
modle, et il est tout fait possible que ce changement casse des fonctionnalits de
lapplication. Ca peut arriver dautant plus facilement que personne ne prend tout fait
le temps de comprendre le modle en entier. Chacun matrise son propre pr carr,
mais ne connait pas les autres zones suffisamment en dtail.
Il suffit de pas grand-chose pour partir dun bon modle et le faire progresser vers un
modle incohrent. La premire ncessit pour un modle est quil soit cohrent, avec
des termes fixs et aucune contradiction. La cohrence interne dun modle est appele
unification. Un projet dentreprise peut avoir un modle qui recouvre lintgralit du
domaine de lentreprise, sans contradictions et sans termes qui se chevauchent. Le
modle dentreprise unifi est un idal difficile atteindre, et parfois a ne vaut mme
pas la peine dessayer. Ce genre de projet requiert les efforts combins de nombreuses
quipes. Les quipes ont besoin dun degr lev dindpendance dans le processus de
dveloppement, parce quelles nont pas le temps de se rencontrer et de dbattre de la
62
Contexte born
Tout modle a un contexte. Quand on a affaire un seul modle, le contexte est
implicite. On na pas besoin de le dfinir. Quand on cre une application cense
63
interagir avec un autre logiciel, par exemple avec une application historique2, il est
clair que la nouvelle application possde ses propres modle et contexte, qui sont
spars du modle et du contexte historiques. Les deux ne peuvent pas tre combins,
mlangs, ou confondus. Mais lorsquon travaille sur une grosse application
dentreprise, il nous faut dfinir un contexte pour chaque modle que nous crons.
Dans tout gros projet, plusieurs modles entrent en jeu. Mais quand on essaie de
combiner des morceaux de code bass sur des modles distincts, le logiciel devient
bugg, peu fiable, et difficile comprendre. La communication entre les membres de
lquipe devient confuse. On ne distingue souvent pas bien dans quel contexte un
modle donn ne devrait pas tre appliqu.
Il ny a pas de formule mathmatique pour diviser un gros modle en modles plus
petits. Essayez de placer dans le mme modle les lments qui sont lis, et qui
forment un concept naturel. Un modle doit tre assez petit pour pouvoir tre assign
une seule quipe. La coopration et la communication au sein dune mme quipe
sont plus fluides et compltes, ce qui favorise le travail des dveloppeurs sur le mme
modle. Le contexte dun modle est lensemble de conditions quon doit appliquer
pour sassurer que les termes utiliss dans le modle prennent un sens prcis.
Lide de base, cest de dfinir le primtre dun modle, de tracer les limites de son
contexte, puis de faire tout ce qui est possible pour prserver son unit. Cest difficile
de maintenir un modle dans un tat pur quand il stend sur lintgralit du projet
dentreprise, mais cest beaucoup plus facile quand il se limite une zone prcise.
Dfinissez explicitement le contexte dans lequel le modle sapplique. Posez des
bornes explicites en termes dorganisation dquipe, dutilisation au sein de parties
spcifiques de lapplication, et de manifestations physiques comme les bases de code
et les schmas de bases de donnes. Essayez de prserver un modle strictement
cohrent lintrieur de ces frontires, et ne vous laissez pas distraire ou embrouiller
par des problmes extrieurs.
Un Contexte born nest pas un Module. Un Contexte born fournit le cadre logique
lintrieur duquel le modle volue. Les Modules sont utiliss pour organiser les
lments dun modle, donc le Contexte born englobe le Module.
Quand diffrentes quipes sont amenes travailler sur le mme modle, elles doivent
faire trs attention ne pas se marcher sur les pieds. Nous devons tre constamment
conscients que des changements dans le modle peuvent casser des fonctionnalits
existantes. Lorsquon utilise des modles multiples, chacun peut travailler librement
sur sa propre partie. Nous connaissons tous les limites de notre modle, et nous restons
Legacy application
64
lintrieur de ses frontires. Nous devons juste nous assurer que le modle reste pur,
cohrent et unifi. Chaque modle supporte plus facilement le refactoring, sans
rpercussion sur les autres modles. La conception peut tre affine et distille afin
dobtenir le maximum de puret.
Il y a un prix payer pour avoir des modles multiples. On doit dfinir les frontires et
les relations entre les diffrents modles. Cela demande du travail en plus et un effort
de conception supplmentaire, et il y aura peut-tre des traductions faire entre les
modles. On ne pourra pas transfrer des objets entre deux modles, ni invoquer
librement un comportement comme sil ny avait pas de frontire. Mais ce nest pas
une tche trs difficile, et les bnfices justifient quon se donne cette peine.
Par exemple, nous voulons crer une application de-commerce pour vendre des
choses sur Internet. Cette application permet aux clients de senregistrer, et collecte
leurs donnes personnelles, dont le numro de carte de crdit. Les donnes sont
conserves dans une base relationnelle. Les clients peuvent se logger, parcourir le site
pour chercher des produits, et passer commande. Lapplication va devoir publier un
vnement chaque fois quune commande est passe, pour que quelquun puisse
expdier larticle demand. Nous voulons aussi construire une interface de reporting
pour crer des rapports, en vue de surveiller le statut des produits disponibles, les
achats qui intressent les clients, ce quils naiment pas, etc. Au dbut, nous
commenons avec un modle qui couvre tout le domaine de le-commerce. Nous
avons cette tentation parce quaprs tout, on nous a demand de crer une seule grosse
application. Mais si nous examinons avec plus dattention la tche qui nous occupe,
nous dcouvrons que lapplication de boutique en ligne nest pas vraiment lie celle
de reporting. Elles ont des responsabilits diffrentes, et elles risquent mme de devoir
utiliser des technologies diffrentes. La seule chose vraiment commune est que les
donnes clients et produits sont conserves dans la base de donnes, et que les deux
applications y accdent.
Lapproche prconise est de crer un modle spar pour chacun des domaines, un
pour la boutique en ligne, et un pour le reporting. Ils peuvent tous deux voluer
librement sans grande proccupation de lautre, et mme devenir des applications
spares. Il peut savrer que lapplication de reporting ait besoin de donnes
particulires que lapplication de vente en ligne devra enregistrer en base, mais part
a elles peuvent se dvelopper indpendamment.
On a besoin dun systme de messagerie qui informe le personnel de lentrept des
commandes qui sont passes, pour quils puissent envoyer les marchandises
commandes. Le personnel du service expditions va utiliser une application qui lui
donne des informations dtailles sur larticle achet, la quantit, ladresse du client, et
les conditions de livraison. Nul besoin que le modle de-commerce couvre les deux
65
domaines dactivit. Il est beaucoup plus simple que lapplication de boutique en ligne
envoie des Objets Valeurs contenant les informations de commande lentrept en
utilisant des messages asynchrones. Il y a indniablement deux modles qui peuvent
tre dvelopps sparment, et nous devons juste nous assurer que linterface entre les
deux marche bien.
Intgration continue
Une fois quun Contexte born a t dfini, nous devons le maintenir dans un tat sain.
Quand un certain nombre de gens travaillent dans le mme Contexte born, le modle
a une forte tendance se fragmenter. Plus lquipe est grosse, plus le problme est de
taille, mais mme trois ou quatre personnes peuvent rencontrer de srieux ennuis. Pour
autant, vouloir dcomposer le systme en contextes de plus en plus petits finit par
provoquer la perte dun niveau dintgration et de cohrence trs utile.
Mme quand une quipe travaille dans un Contexte born, il y a de la place pour
lerreur. Il nous faut communiquer lintrieur de lquipe pour vrifier que nous
comprenons tous le rle jou par chaque lment du modle. Si quelquun ne saisit pas
bien les relations entre objets, il risque de modifier le code dune manire qui rentre en
contradiction avec lintention dorigine. Il est facile de se tromper de cette manire
quand on ne reste pas 100% concentr sur la puret du modle. Un membre de
lquipe peut crire du code qui duplique un code existant sans le savoir, ou ajouter du
code en doublon au lieu de modifier le code actuel, de peur de casser une
fonctionnalit existante.
Un modle nest pas entirement dfini ds le dbut. Il est cr, puis il volue
continuellement sur la base de nouvelles perspectives dans le domaine et de retours
dinformations du processus de dveloppement. Cela veut dire que de nouveaux
concepts risquent dentrer dans le modle, et que de nouveaux lments sont ajouts au
code. Tout cela doit tre intgr dans le modle unifi, et implment en consquence
dans le code. Cest pourquoi lIntgration continue est un procd ncessaire dans le
cadre dun Contexte born. Il nous faut un processus dintgration qui nous assure que
tous les lments ajouts sintgrent harmonieusement dans le reste du modle, et sont
correctement implments dans le code. Nous avons besoin dune procdure pour
fusionner le code. Plus tt nous fusionnons le code, mieux cest. Pour une petite
quipe seule, on recommande une intgration quotidienne. Il nous faut aussi mettre en
place un processus de compilation. Le code fusionn doit tre automatiquement
compil pour pouvoir tre test. Une autre condition ncessaire est de pratiquer des
tests automatiss. Si lquipe possde un outil de test, et a cr une suite de tests, ceux66
ci peuvent tre jous aprs chaque compilation, ainsi toute erreur est signale. On peut
facilement modifier le code pour rparer les erreurs indiques parce quelles sont
prises en charge tt, et ensuite le processus dintgration, compilation et tests repart.
LIntgration continue se base sur lintgration de nouveaux concepts dans le modle,
qui font leur chemin dans limplmentation o ils sont ensuite tests. Toute
incohrence du modle peut tre repre dans limplmentation. LIntgration
continue sapplique un Contexte born, elle nest pas utilise pour traiter les relations
entre Contextes voisins.
Carte de Contexte
Une application dentreprise a de multiples modles, et chaque modle a son propre
Contexte born. Il est conseill dutiliser le contexte comme base de lorganisation
dquipe. Les personnes dune mme quipe communiquent plus facilement, et ils
travaillent plus efficacement intgrer le modle et limplmentation.
Mme si chaque quipe travaille sur son modle, il est bon que tout le monde ait une
ide du tableau densemble. Une Carte de Contexte est un document qui met en
vidence les diffrents Contextes borns et leurs liaisons. Une Carte de Contexte peut
tre un diagramme comme celui-ci-dessous, ou nimporte quel document crit. Le
niveau de dtail peut varier. Ce qui est important, cest que tous ceux qui travaillent
sur le projet la partagent et la comprennent.
Il ne suffit pas davoir des modles unifis distincts. Ils doivent tre intgrs, parce que
chacune des fonctionnalits dun modle nest quune partie du systme entier. A la
fin, les pices doivent tre assembles, et tout le systme doit fonctionner
correctement. Si les contextes ne sont pas clairement dfinis, il est possible quils se
67
chevauchent. Si les liaisons entre contextes ne sont pas mises en vidence, il y a des
chances quelles ne marchent pas quand le systme sera intgr.
Chaque Contexte born doit avoir un nom qui fait partie du Langage omniprsent.
Cela favorise beaucoup la communication dquipe lorsquon parle du systme dans sa
globalit. Tout le monde devrait connaitre les limites de chaque contexte et les
mappages entre contextes et code. Une pratique courante consiste dfinir les
contextes, puis crer les modules de chaque contexte, et utiliser une convention de
nommage pour indiquer le contexte auquel chaque module appartient.
Dans les pages qui suivent, nous allons parler de linteraction entre diffrents
contextes. Nous prsenterons une srie de patterns qui peuvent tre utiliss pour crer
des Cartes de Contexte o les contextes ont des rles clairs et o leurs relations sont
montres. Noyau partag et Client-Fournisseur sont des patterns qui comportent un
haut niveau dinteraction entre contextes. Chemins spars est un pattern quon utilise
quand on veut que les contextes soient fortement indpendants et voluent sparment.
Il y a deux autres patterns qui traitent de linteraction entre un systme et un systme
historique ou un systme externe, ce sont les Services Htes ouverts et les Couches
Anticorruption.
Noyau partag
Quand lintgration fonctionnelle est limite, le cot de lIntgration continue peut tre
jug trop lev. Ca savre particulirement vrai lorsque les quipes nont pas les
comptences ou lorganisation politique ncessaires pour maintenir une intgration
68
continue, ou quand une quipe unique est simplement trop grosse et peu maniable.
Alors, on peut dfinir des Contextes borns spars et former plusieurs quipes.
Des quipes non coordonnes qui travaillent sur des applications troitement lies
peuvent faire la course chacun de leur ct pendant un moment, mais ce quelles
produisent risque de ne pas bien sassembler. Elles peuvent finir par passer plus de
temps sur des couches de traduction et des rajustements quelles nen auraient pass
sur de lIntgration continue le cas chant, ce qui se traduit par des efforts faits en
double et la perte des bnfices dun Langage omniprsent commun.
Par consquent, dsignez un sous-ensemble du modle du domaine que les deux
quipes saccordent partager. Bien sr cela comprend, en plus de cette portion du
modle, la sous-partie du code ou de la conception de la base de donnes qui va avec.
Ce morceau explicitement partag possde un statut spcial, et ne devrait pas tre
modifi sans consultation de lautre quipe.
Intgrez un systme fonctionnel frquemment, mais un peu moins souvent que le
rythme dintgration continue de chaque quipe. Lors de ces intgrations, jouez les
tests des deux quipes.
Lobjectif du Noyau partag est dviter les doublons, tout en gardant deux contextes
spars. Dvelopper sur un Noyau partag demande beaucoup de prcaution. Les deux
quipes peuvent modifier le code du noyau, et elles doivent intgrer leurs
changements. Si les quipes utilisent des copies spares du code du noyau, elles
doivent fusionner le code aussi souvent que possible, au moins une fois par semaine.
Un harnais de test devrait tre mis en place, pour que chaque changement apport au
noyau soit test immdiatement. Toute modification du noyau devrait tre
communique lautre quipe, et toutes les quipes devraient tre informes et tenues
au courant des nouvelles fonctionnalits.
Client-Fournisseur
Parfois, il arrive que deux sous-systmes aient une relation particulire : lun dpend
beaucoup de lautre. Les contextes dans lesquels ces deux sous-systmes existent sont
distincts, et le rsultat des traitements dun systme est dvers dans lautre. Ils nont
pas de Noyau partag, peut-tre parce quil nest conceptuellement pas correct den
avoir un, ou mme car il nest pas techniquement possible que les deux sous-systmes
partagent du code commun. Les deux systmes sont dans une relation ClientFournisseur.
Revenons un prcdent exemple. Nous avons parl plus haut des modles impliqus
dans une application de-commerce qui comporte aussi du reporting et un systme de
69
messages. Nous avons dj dit quil tait bien mieux de crer des modles spars
pour tous ces contextes, car un modle unique serait un goulet dtranglement
permanent et une source de discorde dans le processus de dveloppement. En
supposant que nous nous soyons mis daccord pour avoir des modles spars, quelle
devrait tre la relation entre le sous-systme de boutique web et celui de reporting ? Le
Noyau partag ne semble pas tre un bon choix. Les sous-systmes vont trs
probablement utiliser des technologies diffrentes dans leur implmentation. Lun est
une exprience purement navigateur, tandis que lautre pourrait tre une application
avec une IHM riche. Mme si lapplication de reporting est faite avec une interface
web, les concepts principaux des modles prcdemment cits sont diffrents. Il peut y
avoir de lempitement, mais pas assez pour justifier un Noyau partag. Nous allons
donc choisir une voie diffrente. Dun autre ct, le sous-systme de shopping en ligne
ne dpend pas du tout de celui de reporting. Les utilisateurs de la boutique
lectronique sont des clients qui parcourent les articles sur le web et passent des
commandes. Toutes les donnes sur les clients, les produits et les commandes sont
mises en base. Et cest tout. Lapplication de shopping en ligne ne sintresse pas
vraiment ce qui arrive aux dites donnes.
Dans le mme temps, lapplication de reporting, elle, sy intresse et a besoin des
donnes enregistres par la boutique en ligne. Elle a aussi besoin dinformations
supplmentaires pour assurer le service de reporting quelle propose. Il se peut que les
clients mettent des articles dans leur panier, mais en enlvent avant de rgler. Il se peut
quils visitent certains liens plus que dautres. Ce genre dinformations na pas de sens
pour lapplication de shopping en ligne, mais elles pourraient vouloir dire beaucoup
pour celle de reporting. Par consquent, il faut que le sous-systme fournisseur
implmente des spcifications dont a besoin le sous-systme client. Cest une des
connexions quil peut y avoir entre les deux sous-systmes.
Une autre exigence est lie la base de donnes utilise, et plus prcisment son
schma. Les deux applications vont se servir de la mme base. Si le sous-systme de
boutique en ligne tait le seul y accder, le schma de base de donnes pourrait tre
modifi tout moment pour reflter ses besoins. Mais le sous-systme de reporting
doit aussi accder la base, il a donc besoin de stabilit dans son schma. Il est
inimaginable que le schma de la base ne change pas du tout pendant le processus de
dveloppement. Ca ne posera pas de souci lapplication de shopping en ligne, mais
a sera certainement un problme pour celle de reporting. Les deux quipes vont
devoir communiquer, probablement travailler sur la base de donnes ensemble, et
dcider quand le changement doit tre ralis. Cela va reprsenter une limitation pour
le sous-systme de reporting, car cette quipe prfrerait effectuer la modification
rapidement et continuer dvelopper, au lieu dattendre lapplication de boutique en
ligne. Si lquipe boutique en ligne a le droit de veto, elle peut imposer des limites aux
changements faire sur la base de donnes, ce qui nuit lactivit de lquipe
70
reporting. Si lquipe boutique en ligne peut agir indpendamment, elle rompra les
accords tt ou tard, et implmentera des changements auxquels lquipe de reporting
nest pas prpare. Cest pourquoi ce pattern marche bien si les quipes sont
chapeautes par un mme management. Cela facilite le processus de dcision, et cre
une harmonie.
Cest quand on est face ce genre de scnario que la pice de thtre doit commencer.
Lquipe reporting doit jouer le rle du client, tandis que lquipe boutique en ligne
doit endosser celui du fournisseur. Les deux quipes devraient se rencontrer
rgulirement ou la demande, et discuter comme un client le fait avec son
fournisseur. Lquipe cliente prsente ses besoins, et lquipe fournisseur prpare ses
plans en consquence. Mme si toutes les exigences du client devront tre satisfaites
au final, cest au fournisseur den dcider lagenda de ralisation. Si certains besoins
sont considrs comme vraiment importants, ils devraient tre implments plus tt,
alors que dautres exigences peuvent tre reportes. Lquipe cliente aura aussi besoin
que des donnes dentre et de la connaissance soient partages par lquipe
fournisseur. Le processus circule dans une seule direction, mais cest ncessaire dans
certains cas.
Il faut que linterface entre les deux sous-systmes soit prcisment dfinie. Une suite
de tests de conformit devrait tre cre et utilise pour vrifier tout moment si les
spcifications de linterface sont respectes. Lquipe fournisseur pourra travailler sur
sa conception avec moins de rserve car le filet de scurit de la suite de tests
dinterface lalertera chaque fois quil y aura un problme.
Etablissez une relation client/fournisseur claire entre les deux quipes. Pendant les
sances de planning, ngociez et budgtez des tches pour les exigences du client de
sorte que chacun comprenne lengagement et le calendrier.
Dveloppez conjointement des tests dacceptation automatiss qui valideront
linterface attendue. Ajoutez ces tests la suite des tests de lquipe fournisseur pour
quils soient jous comme faisant partie de son intgration continue. Ces tests rendront
lquipe fournisseur libre de faire des modifications sans craindre deffets de bord dans
lapplication de lquipe cliente.
Conformiste
Une relation Client-Fournisseur est viable quand les deux quipes ont un intrt dans
la relation. Le client est trs dpendant du fournisseur, mais linverse nest pas vrai.
Sil y a un management pour faire fonctionner cela, le fournisseur prtera lattention
ncessaire et coutera les requtes du client. Si le management na pas clairement
71
dcid comment les choses sont censes se passer entre les deux quipes, ou si le
management est dfaillant ou absent, le fournisseur commencera tout doucement tre
plus proccup par son modle et sa conception que par laide apporter au client.
Aprs tout, les membres de lquipe fournisseur ont leurs propre deadlines. Mme si
ce sont des gens bien, volontaires pour aider lautre quipe, la pression des dlais aura
son mot dire, et lquipe cliente va en souffrir. Cela arrive aussi quand les quipes
appartiennent des socits diffrentes. La communication est difficile, et la socit
qui fournit peut ne pas trouver beaucoup dintrt sinvestir dans cette relation. Elle
va soit apporter une aide sporadique, soit refuser de cooprer tout court. Rsultat,
lquipe client se retrouve toute seule, en essayant de se dbrouiller du mieux quelle
peut avec le modle et la conception.
Quand deux quipes de dveloppement ont une relation Client-Fournisseur dans
laquelle lquipe qui fournit nest pas motive pour rpondre aux besoins de lquipe
cliente, cette dernire est dmunie. Laltruisme peut inciter les dveloppeurs
fournisseurs faire des promesses, mais il est peu probable quelles soient tenues. La
croyance en ces bonnes intentions mne lquipe cliente faire de plans se basant sur
des fonctionnalits qui ne seront jamais disponibles. Le projet client sera retard
jusqu ce que lquipe finisse par apprendre vivre avec ce quon lui donne. Une
interface taille pour les besoins de lquipe cliente nest pas prs de voir le jour.
Lquipe cliente a peu doptions. La plus vidente est de se sparer du fournisseur et
dtre compltement seule. Nous examinerons ceci plus tard dans le pattern Chemins
spars. Parfois, les bnfices apports par le sous-systme du fournisseur nen valent
pas la peine. Il peut tre plus simple de crer un modle spar, et de concevoir sans
avoir penser au modle du fournisseur. Mais ce nest pas toujours le cas.
Parfois il y a de la valeur dans le modle du fournisseur, et une connexion doit tre
maintenue. Mais comme lquipe fournisseur naide pas lquipe cliente, cette dernire
doit prendre des mesures pour se protger des changements du modle effectus par le
fournisseur. Elle va devoir implmenter une couche de translation qui connecte les
deux contextes. Il est aussi possible que le modle du fournisseur soit mal conu,
rendant son utilisation malaise. Le contexte client peut tout de mme sen servir, mais
il devrait se protger en utilisant une Couche anticorruption dont nous parlerons plus
loin.
Si le client est oblig dutiliser le modle de lquipe fournisseur, et si celui-ci est bien
fait, cest peut tre le moment de faire preuve de conformisme. Lquipe cliente peut
adhrer au modle du fournisseur et sy conformer entirement. Cela ressemble
beaucoup au Noyau partag, mais il y a une diffrence importante. Lquipe cliente ne
peut pas apporter de changements au noyau. Elle peut simplement lutiliser comme sil
faisait partie de son modle, et construire par-dessus le code existant qui lui est fourni.
72
Couche anticorruption
Nous rencontrons souvent des circonstances o nous crons une application qui est
oblige dinteragir avec du code logiciel historique ou une application spare. Cest
un dfi supplmentaire pour le modlisateur du domaine. Beaucoup dapplications
historiques nont pas t construites en utilisant des techniques de modlisation de
domaine, et leur modle est confus, broussailleux, il est difficile de le comprendre et
de travailler avec. Mme sil a t bien fait, le modle de lapplication historique ne
nous est pas dune grande utilit, car notre modle est probablement assez diffrent.
Nanmoins, il faut quil y ait un certain niveau dintgration entre notre modle et le
modle historique, car cela fait partie des prrequis pour pouvoir utiliser la vieille
application.
Notre systme client peut interagir avec un systme externe de diffrentes manires.
Lune dentre elles est de passer par des connexions rseau. Les deux applications
doivent utiliser les mmes protocoles de communication rseau, et il faut que le client
adhre linterface utilise par le systme externe. Une autre mthode dinteraction est
la base de donnes. Le systme externe travaille avec des donnes stockes dans une
base.
Le
client
est
cens
accder
la
mme
base.
Dans ces deux cas, nous avons affaire des donnes primitives qui sont transfres
entre les systmes. Bien que cela paraisse assez simple, en vrit les donnes
primitives ne contiennent aucune information sur les modles. On ne peut pas prendre
des donnes dans une base et les traiter entirement comme des donnes primitives. Il
y a beaucoup de smantique cache derrire les donnes. Une base de donnes
relationnelle contient des donnes primitives relies dautres, ce qui cre une toile de
relations. La smantique des donnes est trs importante et doit tre prise en
considration : lapplication cliente ne peut pas accder la base et y crire sans
comprendre la signification des donnes utilises. Il faut bien voir que des parties du
modle externe sont refltes dans la base de donnes, et elles viennent sintgrer dans
notre modle.
73
Il y a des chances pour que le modle externe altre le modle client, si on laisse faire
cela. Nous ne pouvons pas ignorer linteraction avec le modle externe, mais nous
devrions faire attention isoler notre propre modle de celui-ci. Nous devrions
construire une Couche anticorruption qui se dresse entre notre modle client et
lextrieur. Du point de vue de notre modle, la Couche anticorruption est une partie
naturelle du modle, elle ne parait pas tre quelque chose dtranger. Elle opre avec
des concepts et des actions familires notre modle. Mais la Couche anticorruption
dialogue avec le modle externe en utilisant le langage externe, pas le langage client.
Cette couche agit comme un traducteur dans les deux sens entre deux domaines et
langages. Le meilleur rsultat possible, cest que le modle client reste pur et cohrent
sans tre contamin par le modle externe.
Comment implmenter la Couche anticorruption ? Une trs bonne solution consiste
voir la couche comme un Service du point de vue du modle client. Un Service est trs
facile utiliser parce quil fait abstraction de lautre systme et nous permet de nous
adresser lui dans nos propres termes. Cest le Service qui va faire la traduction
requise, donc notre domaine reste isol. En ce qui concerne limplmentation concrte,
le Service va tre conu comme une Faade (voir Design Pattern de Gamma et al.,
1995). Dautre part, la Couche anticorruption va trs probablement avoir besoin dun
Adaptateur. LAdaptateur vous permet de convertir linterface dune classe en une
autre qui sera comprise par le client. Dans notre cas, lAdaptateur nenrobe pas
ncessairement une classe, car son travail consiste assurer la traduction entre deux
systmes.
La couche anticorruption peut contenir plus dun Service. Pour chaque Service il y a
une Faade qui correspond, et chaque Faade on adjoint un Adaptateur. On ne doit
74
pas utiliser un seul Adaptateur pour tous les Services, parce quon lencombrerait de
fonctionnalits htroclites.
Il nous reste encore un composant ajouter. LAdaptateur soccupe denvelopper le
comportement du systme externe, mais nous avons aussi besoin de convertir des
objets et des donnes. Cela se fait au moyen dun traducteur. Ca peut tre un objet trs
simple, avec peu de fonctionnalits, qui rpond au besoin basique de traduire des
donnes. Si le systme externe a une interface complexe, il peut savrer plus
judicieux dajouter une Faade supplmentaire entre les adaptateurs et cette interface
externe. Cela va simplifier le protocole de lAdaptateur, et le sparer de lautre
systme.
Chemins spars
Jusquici, nous avons cherch des faons dintgrer des sous-systmes, de les faire
travailler ensemble, et ce de telle manire que le modle et la conception restent sains.
Cela demande des efforts et des compromis. Les quipes qui travaillent sur ces soussystmes doivent passer un temps considrable rgler les relations entre eux. Ils
peuvent tre obligs de faire constamment des fusions de leur code, et deffectuer des
tests pour sassurer quils nont rien cass. Parfois, il arrive quune des quipes doive
passer un temps considrable simplement pour implmenter quelques exigences dont
lautre quipe a besoin. Il faut aussi faire des compromis. Cest une chose de
dvelopper quand on est indpendant, de choisir les concepts et associations
librement ; cen est une tout autre de devoir sassurer que notre modle sintgre dans
le framework dun autre systme. On va peut-tre devoir transformer le modle juste
pour quil fonctionne avec lautre sous-systme. Ou introduire des couches spciales
qui assurent les traductions entre les deux sous-systmes. Il y a des fois o on est
oblig de faire a, mais en certaines occasions on peut emprunter une voie diffrente.
Nous devons valuer prcisment les bnfices de lintgration des deux systmes et
lutiliser seulement si on en tire une vraie valeur. Si nous arrivons la conclusion que
lintgration apporte plus dennuis quelle nest utile, alors on devrait opter pour des
Chemins spars.
Le pattern Chemins spars concerne le cas o une application dentreprise peut tre
constitue de plusieurs applications plus petites qui nont pas grand-chose ou rien en
commun dun point de vue modlisation. Il y a un seul jeu de spcifications et, vu de
lutilisateur, il sagit dune seule application, mais ct conception et modlisation,
cela peut tre fait en utilisant des modles spars avec des implmentations distinctes.
Ce quon devrait faire, cest regarder les spcifications et voir si elles peuvent tre
75
divises en deux ensembles ou plus qui nont pas grand-chose en commun. Si cest
ralisable, alors on peut crer des Contextes borns spars et les modliser
indpendamment. Cela a lavantage de nous donner la libert de choisir les
technologies utilises pour limplmentation. Les applications quon cre peuvent
partager une IHM fine commune qui agit comme un portail, avec des liens ou des
boutons qui servent accder chaque application. Cest une intgration mineure qui
a trait lorganisation des applications plutt quau modle sous-jacent.
Avant de partir sur des Chemins spars, nous devons nous assurer que nous ne
reviendrons pas un systme intgr. Les modles dvelopps indpendamment sont
trs difficiles rintgrer. Ils ont si peu en commun que a nen vaut simplement pas
la peine.
76
Distillation
La distillation est le procd qui consiste sparer les substances qui composent un
mlange. Le but de la distillation est dextraire une substance particulire du mlange.
Pendant le processus de distillation, on peut obtenir des sous-produits, et ils peuvent
aussi avoir un intrt.
Un gros domaine aura un gros modle, mme aprs que nous layons raffin et cr
beaucoup dabstractions. Il peut rester volumineux mme suite de nombreux
refactorings. Dans une situation comme celle-l, il est peut-tre temps de distiller.
Lide est de dfinir un Cur de Domaine qui reprsente lessence du domaine. Les
sous-produits du processus de distillation seront des Sous-domaines gnriques qui
vont contenir dautres parties du domaine.
Dans la conception dun gros systme, il y a tellement de composants auxiliaires, tous
compliqus et tous absolument ncessaires au succs, que lessence du modle du
domaine, le vrai capital mtier, peut tre obscurci et nglig.
Quand on travaille avec un modle vaste, on devrait essayer de sparer les concepts
essentiels des concepts gnriques. Au dbut, nous avons donn lexemple dun
systme de surveillance du trafic arien. Nous avons dit quun Plan de Vol contenait la
Route quun avion est destin suivre. La Route semble tre un concept
continuellement prsent dans ce systme. Mais en ralit, ce concept est gnrique et
pas essentiel. Le concept de Route est utilis dans de nombreux domaines, et un
modle gnrique peut tre conu pour le dcrire.
Lessence de la surveillance de trafic arien se situe ailleurs. Le systme de contrle
connait la route que lavion doit suivre, mais il reoit aussi des informations dun
rseau de radars qui dtectent lavion dans le ciel. Ces donnes montrent le vritable
chemin suivi par lavion, et il est gnralement diffrent du chemin prescrit.
Le systme va devoir calculer la trajectoire de lavion en se basant sur ses paramtres
de vol actuels, les caractristiques de lavion et la mto. La trajectoire est un chemin
4 dimensions qui dcrit compltement la route que lavion va suivre au cours du
temps. La trajectoire peut tre calcule pour les deux minutes qui suivent, les quelques
dizaines de minutes venir ou les deux prochaines heures. Chacun de ces calculs
favorise le processus de prise de dcision. Tout lintrt de calculer la trajectoire de
lavion est de voir sil y a une chance pour que le chemin de cet avion en croise un
77
autre. Dans le voisinage des aroports, lors des dcollages et des atterrissages,
beaucoup davions font des cercles en lair ou manuvrent. Si un avion drive de sa
route prvue, il est fort possible quun crash se produise. Le systme de contrle du
trafic arien va calculer les trajectoires des avions, et diffuser une alerte sil y a la
possibilit dune intersection. Les aiguilleurs du ciel vont devoir prendre des dcisions
rapides, dirigeant les avions afin dviter la collision. Quand les avions sont plus
loigns, les trajectoires sont calcules sur de plus longues priodes, et il y a plus de
temps pour ragir.
Le module qui synthtise la trajectoire de lavion partir des donnes disponibles
constitue ici le cur du systme mtier. Il devrait tre dsign comme tant le cur de
domaine. Le modle de routage relve plus dun domaine gnrique.
Le Cur de Domaine dun systme dpend de la manire dont nous regardons ce
systme. Un systme de routage simple verra la Route et ses dpendances comme un
lment central de la conception. Le systme de surveillance du trafic arien
considrera la Route comme un sous-domaine gnrique. Le Cur de Domaine dune
application peut devenir un sous-domaine gnrique chez une autre. Il est important
didentifier correctement le Cur, et de dterminer les relations quil entretient avec
les autres parties du modle.
Faites rduire le modle. Trouvez le Cur de Domaine et proposez un moyen de le
distinguer facilement de la masse de modles et de code auxiliaires. Mettez laccent
sur les concepts les plus valables et les plus spcialiss. Adoptez un cur relativement
petit.
Mettez vos meilleurs talents sur le Cur de Domaine, et recrutez en consquence.
Concentrez vos efforts sur le Cur pour trouver un modle approfondi et dvelopper
un design souple suffisamment pour satisfaire la vision du systme. Justifiez les
investissements sur toute autre partie en les mettant en regard du bnfice apport au
Cur distill.
Il est important dassigner aux meilleurs dveloppeurs la tche dimplmenter le Cur
de Domaine. Les dveloppeurs ont gnralement tendance aimer les technologies,
apprendre le meilleur et tout dernier langage, tre attirs plus par linfrastructure que
par la logique mtier. La logique mtier dun domaine semble tre ennuyeuse et peu
gratifiante pour eux. Aprs tout, quoi bon apprendre les spcificits des trajectoires
davions ? Quand le projet sera termin, toute cette connaissance sera de lhistoire
ancienne,
et
aura
trs
peu
dintrt.
Mais la logique mtier du domaine est au centre de celui-ci. Des erreurs dans la
conception et limplmentation du cur peuvent mener labandon complet du projet.
Si la logique mtier centrale ne fait pas son travail, toutes les paillettes et dorures
technologiques ne vaudront rien.
78
79
trait. Linterface utilise pour dialoguer avec le sous-domaine doit tre dfinie
et communique lautre quipe.
3. Modle existant. Une solution pratique consiste utiliser un modle dj cr.
Il existe certains livres qui ont publi des patterns danalyse, et ils peuvent tre
utiliss comme source dinspiration pour nos sous-domaines. Il se peut quil ne
soit pas possible de recopier les patterns ad litteram, mais beaucoup dentre eux
peuvent tre utiliss avec de petites modifications.
4. Implmentation maison. Cette solution a lavantage daccomplir le meilleur
niveau dintgration. Cela veut bien entendu dire des efforts supplmentaires, y
compris le fardeau de la maintenance.
80
81
6
DDD compte aujourdhui :
une interview dEric Evans
InfoQ.com interviewe le fondateur de Domain Driven Design, Eric Evans, pour
replacer DDD dans le contexte daujourdhui :
82
donne rellement ce que nous attendons. Mais les gens font plus dexpriences que
jamais dans ce domaine, et cela me donne espoir.
Aujourdhui, pour autant que je sache, la plupart des gens qui tentent dappliquer DDD
travaillent en Java ou .NET, et quelques-uns en Smalltalk. Donc cest la mouvance
positive du monde Java qui profite des effets immdiats.
Que sest-il pass dans la communaut DDD depuis que vous avez crit votre livre ?
Quelque chose qui me passionne, cest quand les gens prennent les principes dont jai
parl dans mon livre et les utilisent dune manire que je naurais jamais souponne.
Il y a par exemple lutilisation du design stratgique chez StatOil, la compagnie
nationale de ptrole norvgienne. Les architectes l-bas ont crit un retour
dexprience
ce
propos.
(Vous
pouvez
le
lire
ladresse
http://domaindrivendesign.org/articles/.)
Entre autres, ils ont pris la carte de contexte et lont applique lvaluation de
logiciels du march dans des prises de dcisions achat/ralisation.
Pour citer un exemple assez diffrent, certains dentre nous ont explor dautres
problmatiques en dveloppant une bibliothque de code Java contenant quelques
objets du domaine fondamentaux dont ont besoin beaucoup de projets. Les gens
peuvent consulter tout a ladresse :
http://timeandmoney.domainlanguage.com
Nous avons explor, par exemple, jusquo lon peut pousser lide dun langage
fluent spcifique au domaine, tout en continuant implmenter les objets en Java.
Il y a pas mal de choses qui se passent. Japprcie toujours quand des personnes me
contactent pour me faire part de ce quils font.
Avez-vous des conseils pour les gens qui essaient dapprendre DDD aujourdhui ?
Lisez mon livre ! ;-) Essayez aussi dutiliser Timeandmoney dans votre projet. Un de
nos objectifs dorigine tait de proposer un bon exemple grce auquel les gens
pourraient apprendre en lutilisant.
Une chose quil faut avoir en tte, cest que DDD est principalement pratiqu au
niveau de lquipe, donc au besoin vous devrez peut-tre vous faire vanglisateur. Sur
un plan plus raliste, vous pourriez aussi chercher un projet o les gens font dj un
effort pour faire du DDD.
Gardez lesprit certains piges de la modlisation de domaine :
1)
85
2)
3)
Nessayez pas dappliquer DDD tout. Tracez une carte de contexte et dcidez
o vous allez faire des efforts sur DDD ou pas. Ensuite, ne vous en souciez pas
hors de ces limites.
4)
86
87
Aggregate
Avance majeure
Breakthrough
Carte de Contexte
Context Map
Chemins spars
Separate Ways
Cur de Domaine
Core Domain
Model-Driven Design
Contexte born
Bounded Context
Couche anticorruption
Anticorruption Layer
Entit
Entity
Entrept
Repository
Fabrique
Factory
Fabrique abstraite
Abstract Factory
Langage omniprsent
Ubiquitous Language
Mthode de fabrication
Factory Method
Modle du domaine
Domain Model
Noyau partag
Shared Kernel
Objet-Valeur
Value Object
Racine dagrgat
Aggregate Root
Sous-domaine gnrique
Generic Subdomain
88