-
Notifications
You must be signed in to change notification settings - Fork 2
/
MDD.qmd
723 lines (573 loc) · 31.4 KB
/
MDD.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
# Modèle du domaine (MDD, modèle conceptuel) {#sec-mdd}
Les MDD sont expliqués en détail dans le chapitre 9\ {{< fa solid book >}}, mais voici des points importants:
- Un **modèle du domaine** est un modèle conceptuel qui représente les concepts importants, modélisés comme classes conceptuelles, du domaine de l'application.
- Une classe conceptuelle selon Craig Larman est une abstraction qui aide à modéliser et à comprendre les entités et leurs propriétés dans un domaine spécifique, fournissant une base pour la conception ultérieure du système.
- Il peut y avoir des relations entre les classes conceptuelles, appelées **associations**.
- Les classes conceptuelles ne sont pas des classes logicielles. Ainsi, selon la méthodologie de Larman, *elles n'ont pas de méthodes*.
- Les classes conceptuelles ont des noms commençant avec une lettre majuscule, par exemple `Joueur`, et elles ne sont jamais au pluriel; par exemple, une classe ne peut pas prendre le nom ~~`Joueurs`~~.
## Classes conceptuelles
Il y a trois stratégies pour identifier les classes conceptuelles:
1. Réutiliser ou modifier des modèles existants.
2. Utiliser une liste de catégories.
3. Identifier des groupes nominaux.
### Catégories pour identifier des classes conceptuelles {#sec-categoriesClasses}
:Extrait du tableau 9.1\ {{< fa solid book >}}
**Catégorie** | **Exemples**
:----------|:----------
**Transactions d'affaires**: Elles sont essentielles, commencez l'analyse par les transactions. | *Vente*, *Attaque*, *Réservation*, *Inscription*, *EmpruntVélo*
**Lignes d'une transaction**: Éléments compris dans une transaction. | *LigneArticles*, *ExemplaireLivre*, *GroupeCours*
**Produit ou service lié à une transaction ou à une ligne de transaction**: Pour quel concept sont faites des transactions? |*Article*, *Vélo*, *Vol*, *Livre*, *Cours*
**Où la transaction est-elle enregistrée?** | *Caisse*, *GrandLivre*, *ManifesteDeVol*
**Rôle des personnes liées à la transaction**: Qui sont les parties impliquées dans une transaction? | *Caissier*, *Client*, *JoueurDeMonopoly*, *Passager*
**Organisations liées à la transaction**: Quelles sont les organisations impliquées dans une transaction? | *Magasin*, *CompagnieAérienne*, *Bibliothèque*, *Université*
**Lieu de la transaction, lieu du service** | *Magasin*, *Aéroport*, *Avion*, *Siège*, *LocalCours*
**Événements notables, à mémoriser** | *Vente*, *Paiement*, *JeuMonopoly*, *Vol*
**Objets physiques**: Importants surtout lorsqu'il s'agit d'un logiciel de contrôle d'équipements ou de simulation. | *Article*, *Caisse*, *Plateau*, *Pion*, *Dé*, *Vélo*
**Description d'entités**: Voir section 9.13\ {{< fa solid book >}} pour plus d'informations. | *DescriptionProduit*, *DescriptionVol*, *Livre* (en opposition avec *Exemplaire*), *Cours* (en opposition avec *CoursGroupe*)
**Catalogues**: Les descriptions se trouvent souvent dans des catalogues. | *CatalogueProduits*, *CatalogueVols*, *CatalogueLivres*, *CatalogueCours*
**Conteneurs**: Un conteneur peut contenir des objets physiques ou des informations. | *Magasin*, *Rayonnage*, *Plateau*, *Avion*, *Bibliothèque*
**Contenu d'un conteneur** | *Article*, *Case* (sur un *Plateau* de jeu), *Passager*, *Exemplaire*
**Autres systèmes externes** | *SystèmeAutorisationPaiementsÀCrédit*, *SystèmeGestionBordereaux*
**Documents financiers, contrats, documents légaux** | *Reçus*, *GrandLivre*, *JournalDeMaintenance*
**Instruments financiers** | *Espèces*, *Chèque*, *LigneDeCrédit*
**Plannings, manuels, documents régulièrement consultés pour effectuer un travail** | *MiseÀJourTarifs*, *PlanningRéparations*
## Attributs
Les attributs sont le sujet de la section 9.16\ {{< fa solid book >}}.
Comme c'est le cas pour les classes et les associations, on fait figurer les attributs *quand les cas d'utilisation suggèrent la nécessité de mémoriser des informations*.
Pour l'UML, la syntaxe complète d'un attribut est:
**visibilité nom: type multiplicité = défaut {propriété}**
Voici des points importants:
- *Le type d'un attribut est important, et il faut le spécifier dans un MDD*, même si dans le livre de @craig_uml_2005, il y a plusieurs exemples sans type.
- Ne vous souciez pas de la visibilité des attributs dans un MDD.
- Faites attention à la confusion des attributs et des classes. Si l'on ne pense pas un concept *X* en termes alphanumériques dans le monde réel, alors il s'agit probablement d'une classe conceptuelle. Par exemple, dans le monde réel, une université n'est composée ni de chiffres ni de lettres. Elle doit être une classe conceptuelle. Voir la section 9.12\ {{< fa solid book >}}.
- De la même manière, faites attention aux informations qui sont mieux modélisées par des associations. Par exemple, sur la @fig-MDD-jeu-de-risk, la classe `Pays` n'a pas un *attribut* `joueur:Joueur` (qui contrôle le Pays); elle a plutôt une *association* avec la classe `Joueur` et un verbe `contrôle`.
::: {.callout-warning appearance="simple"}
Il est vrai que dans un langage de programmation comme Java, les associations doivent être les attributs dans les classes, car il s'agit des classes *logicielles*.
Cependant, dans un modèle du domaine, on évite des attributs si une association peut mieux décrire la relation.
La relation relie visuellement les deux classes conceptuelles et elle est décrite avec un verbe.
:::
## Associations
Les associations dans le MDD sont le sujet de la section 9.14\ {{< fa solid book >}}.
Il faut se référer au contenu du livre de Larman pour les détails.
Une association est une relation entre des classes (ou des instances de classes).
Elle indique une connexion significative ou intéressante.
Voici des points importants:
- Il est facile de trouver beaucoup d'associations, mais il faut se limiter à celles qui doivent être conservées un certain temps.
Pensez à la **mémorabilité** d'une association dans le contexte du logiciel à développer. Par exemple, considérez les associations de la @fig-MDD-jeu-de-risk:
- Il existe une association entre `Joueur` et `Pays`, car il est important de savoir quel joueur contrôle quel pays dans le jeu Risk.
- Il n'y a pas d'association entre `JeuRisk` et `Attaque`, même si les attaques font partie du jeu. Il n'est pas essentiel de mémoriser l'historique de toutes les attaques réalisées dans le jeu.
- Il y a des associations dérivées de la liste des associations courantes. Voir le @tbl-associations-courantes.
- En UML, les associations sont représentées par des lignes entre les classes.
- Elles sont nommées (avec un verbe commençant par une lettre majuscule).
- Des verbes simples comme "A", "Utilise", "Possède", "Contient", etc. sont généralement des choix médiocres, car ils n'aident pas notre compréhension du domaine. Essayez de trouver des verbes plus riches, si possible.
- Une flèche (triangle) de "sens de lecture" optionnelle indique la direction dans laquelle lire l'association. Si la flèche est absente, on lit l'association de gauche à droite ou de haut en bas.
- Les extrémités des associations ont une expression de la multiplicité indiquant une relation numérique entre les instances des classes.
Vous pouvez en trouver plusieurs exemples sur la @fig-MDD-jeu-de-risk.
- Les associations ne doivent pas être représentées avec des attributs.
Les associations servent à représenter les relations purement conceptuelles afin de documenter le domaine.
Elles ne visent pas à documenter la structure des données ou les instances de variables qu'on retrouve dans le logiciel.
Contrairement aux associations des diagrammes de classes logicielles, ce ne sont pas toutes les associations conceptuelles qui seront implémentées dans le logiciel.
: Extrait du tableau 9.2\ {{< fa solid book >}} (liste d'associations courantes) {#tbl-associations-courantes}
**Catégorie** | **Exemples**
:----------|:----------
**A est une transaction liée à une transaction B**| *PaiementEnEspèces -- Vente* \
*Réservation -- Annulation*\newline
**A est un élément d'une transaction B**| *LigneArticles -- Vente*\newline
**A est un produit pour une transaction (ou un élément de transaction) B**| *Article -- LigneArticles* (ou *Vente*) \
*Vol -- Réservation*\newline
**A est un rôle lié à une transaction B**| *Client -- Paiement* \
*Passager -- Billet*\newline
**A est une partie logique ou physique de B**| *Tiroir -- Registre* \
*Case -- Plateau* \
*Siège -- Avion*\newline
**A est physiquement ou logiquement contenu dans B**| *Registre -- Magasin* \
*Joueur -- Monopoly* \
*Passager -- Avion*\newline
**A est une description de B**| *DescriptionProduit -- Article* \
*DescriptionVol -- Vol*\newline
**A est connu/consigné/enregistré/saisi dans B**| *Vente -- Registre* \
*Pion -- Case* \
*Réservation -- ManifesteDeVol*\newline
**A est un membre de B**| *Caissier -- Magasin* \
*Joueur -- Monopoly* \
*Pilote -- CompagnieAérienne*\newline
**A est une sous-unité organisationnelle de B**| *Rayon -- Magasin* \
*Maintenance -- CompagnieAérienne*\newline
**A utilise, gère ou possède B**| *Caissier -- Registre* \
*Joueur -- Pion* \
*Pilote -- Avion*\newline
**A est voisin de B**| *Article -- Article* \
*Case -- Case* \
*Ville -- Ville*
## Attributs dérivés
Les attributs dérivés sont expliqués en détail dans la section 9.16\ {{< fa solid book >}}.
Il s'agit des attributs qui sont calculés à partir d'autres informations reliées à la classe.
Ils sont indiqués par le symbole **`/`** devant leur nom.
L'exemple à la @fig-MDD-attribut-derive s'applique à la règle du jeu Risk spécifiant qu'un joueur reçoit un certain nombre de renforts selon le nombre de pays occupés. La classe Joueur pourrait avoir un attribut dérivé `/nbPaysOccupés` qui est calculé selon le nombre de Pays contrôlés par le joueur.
```{.plantuml genurl="true" #fig-MDD-attribut-derive caption="`nbPaysOccupés` est un attribut dérivé. Sa valeur sera calculée selon le nombre de pays de l'association."}
@startuml
!include ecriture.pumlinclude
scale 1
hide empty members
class Joueur {
nom : String
<color:blue>/nbPaysOccupés : int</color>
}
class Pays {
nom : String
}
Joueur "1" -- "1..*" Pays : Contrôle >
@enduml
```
## Exemple de MDD pour le jeu Risk
La @fig-MDD-jeu-de-risk est un MDD pour le jeu Risk, selon [l'exemple](#exemple-jeu-de-risk) mentionné dans le chapitre sur les cas d'utilisation.
Commençons par la classe `JeuRisk`, qui est l'objet racine du modèle.
Il est relié à la classe `Joueur`, puisqu'un joueur "joue" à `JeuRisk` (notez le triangle pour le sens de lecture).
Selon les cardinalités de l'association entre ces deux classes, il peut y avoir entre deux (2) et six (6) personnes qui jouent au jeu.
Le jeu "inclut" cinq objets de la classe `Dé`, mais un `Joueur` jette un, deux ou trois dés (selon la règle du jeu Risk).
L'association entre `Joueur` et `Pays` a un verbe "contrôle", qui est un exemple de verbe plus riche que "possède" ou "a".
L'association entre `Continent` et `Pays` représente la composition des territoires (un synonyme pour pays) des différents continents, soit 4 (pour l'Amérique du sud et l'Océanie), 6 (pour l'Afrique), 7 (pour l'Europe), 9 (pour l'Amérique du nord) et 12 (pour l'Asie).
Si vous regardez tout le modèle, vous verrez qu'il représente visuellement beaucoup d'éléments du jeu.
```{.plantuml genurl="true" #fig-MDD-jeu-de-risk caption="Modèle du domaine du jeu Risk."}
@startuml
!include ecriture.pumlinclude
scale 1
hide empty members
class Joueur {
nom : String
/nbPaysOccupés : int
}
class Dé {
valeur : int
}
class JeuRisk
class "PlateauRisk" as PR
class Pays {
nom : String
}
class Attaque {
nbAttaquant : int
nbDéfenseur : int
}
class Occupation {
nbRégiments : int
}
PR "1" *-- "42" Pays : Contient >
PR "1" *-- "6" Continent : Est-\ndivisé-\nen >
Continent "1" *-- "4, 6,\n7, 9,\n12" Pays : Groupe >
Pays "1" -- "1..*" Pays : Est-voisin-de >
JeuRisk "1" -l- "1" PR : Est-joué-sur >
JeuRisk "1" -d- "5" Dé : Inclut >
' ligne suivante contient un espace large ( )
Joueur " 2:6" -l- "1" JeuRisk : Joue >
Joueur "1" -- "1..*" Pays : Contrôle >
(Joueur, Pays) .. Occupation
'Joueur "1" -- "*" Régiment : Contrôle >
'Pays "1" -l- "*" Régiment : < Protège-\nou-\nattaque
Pays "1" -l- "1..*" Attaque : Lance >
Pays "1" -- "1..*\n" Attaque : Défend-contre >
Joueur "1" -- "1,2,3" Dé : Jette >
@enduml
```
## Classes de "description" et classes de catalogue
Deux catégories de classes conceptuelles qui vont de pair sont les *descriptions d'entités* et les *catalogues* qui agrègent les descriptions.
Elles sont expliquées en détail dans la section 9.13\ {{< fa solid book >}}.
Voici des conditions pour utiliser correctement une classe de description d'une autre classe "X":
- Il faut disposer de la description d'un produit ou d'un service "X" indépendamment de l'existence actuelle des "X". Par exemple, il pourrait y avoir une rupture de stock d'un Produit (aucune instance actuelle), mais on a besoin de connaître son prix. La classe DescriptionProduit permet d'avoir cette information, même s'il n'y a plus d'instances de Produit.
Un autre exemple est un trimestre où un cours *LOG711* ne se donne pas (il n'y a pas de GroupeCours de _LOG711_ dans le trimestre actuel).
Alors, une classe Cours (qui joue le rôle de description) sert pour spécifier le nombre de crédits, les cours préalables, etc.
- La suppression d'instances de la classe "X" entraîne la perte de l'information qui doit être mémorisée, mais qui a été incorrectement associée à l'entité en question.
- La classe de description réduit la duplication des informations.
La @fig-MDD-CoursGroupeCoursDescription présente une classe de description pour le contexte de cours et de groupe-cours.
```{.plantuml genurl="true" #fig-MDD-CoursGroupeCoursDescription caption="La classe Cours joue le rôle de description d'entités (les groupes-cours)."}
@startuml
!include normal.pumlinclude
hide empty members
scale 1
hide empty members
class "GroupeCours" as GC {
numéro : int
trimestre : Trimestre
...
}
class "Cours" as C #ddffdd {
nom : Texte
nbCrédits : int
...
}
class "Catalogue\nCours" as CP #ddffdd
C "1" -- "*" GC : Décrit >
C "1" -- "*" C : Est-préalable-à >
CP "1" - "*" C : Répertorie >
note bottom of C
Classe de « description ». Une instance de Cours peut exister
indépendamment de l'existence d'un GroupeCours qu'elle décrit
(par exemple, avant qu'un cours soit donné la première fois).
Elle réduit également la duplication des informations (le nom et
le nombre de crédits ne sont pas stockés dans chaque GroupeCours).
end note
@enduml
```
::: {.callout-warning}
Attention de ne pas faire l'erreur naïve d'utiliser une classe de description simplement pour "décrire" une autre classe. Voir la @fig-MDD-ErreurDescription pour un exemple.
:::
```{.plantuml genurl="true" #fig-MDD-ErreurDescription caption="Illustration d'une erreur fréquente: utiliser une classe de description sans justification."}
@startuml
!include normal.pumlinclude
hide empty members
scale 1
hide empty members
class "Client" as GC {
}
class "Description\nClient" as C #ffdddd {
nom : Texte
identifiant : IDClient
...
}
class "Catalogue\nClients" as CP #ffdddd
C "1" -- "1" GC : Décrit >
CP "1" -r- "*" C : Répertorie >
note bottom of C
<size:14><#red:frowning:></size> Mauvaise classe de « description ». Il n'est pas nécessaire
d'avoir cette classe, car les clients sont décrits dans leur
propre classe Client. Si un client n'existe pas, il n'a pas de
sens dans le MDD. Les informations ne seraient pas dupliquées
s'il n'y avait pas cette classe (chaque client a un nom et un
identifiant unique).
end note
@enduml
```
## Classes d'association
Les classes d'association dans un MDD sont le sujet de la section F26.10/A31.10\ {{< fa solid book >}}.
::: {.callout}
Une classe d'association permet de traiter une association comme une classe et de la modéliser avec des attributs.
:::
Il pourrait être utile d'avoir une classe d'association dans un MDD:
- si un attribut est lié à une association;
- si la durée de vie des instances de la classe d'association dépend de l'association;
- s'il y a une association *N*-*N* entre deux concepts et des informations liées à l'association elle-même.
L'exemple illustré sur la @fig-MDD-classe-association explique la nécessité d'une classe d'association Occupation.
Lorsqu'un Joueur contrôle un Pays, il doit déployer des armées dans ce dernier.
Le MDD pourrait avoir un attribut `nbRégiments` dans la classe Pays.
Cependant, l'attribut `nbRégiments` est lié à l'association entre le Joueur et le Pays qu'il contrôle, alors on décide d'utiliser une classe d'association.
Si un Joueur envahit un Pays, la nouvelle instance de la classe d'association Occupation sera créée (avec la nouvelle association).
Pourtant, cette instance d'Occupation sera détruite si un autre Joueur arrive à prendre le contrôle du Pays.
Alors, la durée de vie de cette instance dépend de l'association.
Voir le livre de @craig_uml_2005 pour plus d'exemples.
```{.plantuml genurl="true" #fig-MDD-classe-association caption="Classe d'association dans le MDD Jeu Risk."}
@startuml
!include ecriture.pumlinclude
scale 1
hide empty members
class Joueur {
nom : String
/nbPaysOccupés : int
}
class Pays {
nom : String
}
class Occupation {
nbRégiments : int
}
Joueur "1" -- "1..*" Pays : Contrôle >
(Joueur, Pays) .. Occupation
@enduml
```
## Affinement du MDD
Lorsqu'on modélise un domaine, il est normal de commencer par un modèle simple (à partir d'un ou de deux cas d'utilisation) et ensuite de l'affiner dans les itérations suivantes, où l'on y intègre d'autres éléments plus subtils ou complexes du problème qu'on étudie.
Les détails de cette approche sont présentés dans le chapitre F26/A31\ {{< fa solid book >}}.
Bien que la matière soit présentée plus tard dans le livre, ce sont des choses à savoir pour la modélisation d'un domaine, même dans une première itération.
Voici un résumé des points importants traités dans ce chapitre, dont quelques-uns ont déjà été présentés plus haut:
- Composition, par exemple la classe Continent qui groupe les Pays sur la @fig-MDD-jeu-de-risk. Larman propose d'utiliser la composition lorsque:
- la durée de vie du composant est limitée à celle du composite (lorsqu'un objet Continent est instancié, ça doit grouper des instances de Pays pour être cohérent), il existe une dépendance création-suppression de la partie avec le tout (ça ne fait pas de sens de supprimer un objet Pays d'une instance de Continent dans le jeu Risk);
- il existe un assemblage logique ou physique évident entre le tout et les parties (on ne peut construire un Continent sans les Pays);
- certaines propriétés du composite, comme son emplacement, s'étendent aux composants;
- les opérations que l'on peut appliquer au composite, telles que destruction, déplacement et enregistrement, se propagent aux composants.
- Généralisation et spécialisation (super classes conceptuelles et sous-classes conceptuelles) [voir @craig_uml_2005 pour les exemples et les directives], notamment la règle des 100% (conformité à la définition) et la règle "est-un" (appartenance à l'ensemble).
- Attribut dérivé, par exemple, `/nbPaysOccupés` dans la classe Joueur est un attribut dérivé de l'association entre Joueur et Pays (@fig-MDD-attribut-derive).
- Classes conceptuelles abstraites, dont une instance n'existe pas dans la vraie vie, mais qui servent à regrouper des classes conceptuelles similaires.
- Hiérarchies dans un MDD et héritage dans l'implémentation.
- Noms de rôles.
- Organisation des classes conceptuelles en packages (surtout lorsque le MDD contient un nombre important de classes conceptuelles).
## FAQ MDD
### Y a-t-il un MDD pour chaque cas d'utilisation?{#mddchaquecasutilisation}
Selon la méthodologie de ce manuel, bien qu'une application ait souvent plusieurs fonctionnalités (cas d'utilisation), il n'y a qu'un seul MDD.
Cela dit, le MDD est comme un fichier de code source, puisque sa *version* peut évoluer avec le projet.
Le MDD évoluera normalement après chaque itération, car on fait une nouvelle analyse pour les nouvelles fonctionnalités visées dans l'itération.
Au début du projet, le MDD est plus simple, puisqu'il porte sur seulement les cas d'utilisation ciblés à la première itération.
Le MDD devient plus riche au fur et à mesure qu'on avance dans les itérations, parce qu'il modélise davantage de concepts reliés aux problèmes traités par les nouvelles fonctionnalités à réaliser.
Par exemple, la version initiale du MDD (chapitre 9\ {{< fa solid book >}}) ne traite pas la fonctionnalité de paiement par carte de crédit.
Les classes conceptuelles modélisant la problématique de paiement par carte de crédit sont absentes dans le MDD initial.
Plus tard (après plusieurs itérations, dans le chapitre sur le raffinement du MDD), on voit un MDD beaucoup plus riche qui reflète la modélisation des concepts reliés à des fonctionnalités comme les paiements par carte de crédit, les demandes d'autorisation de paiement, etc.
### Un **modèle du domaine** est-il la même chose qu'un **modèle de données**? {#mdd_donnees}
Voici la réponse de Craig Larman [-@craig_uml_2005] dans la section 9.2\ {{< fa solid book >}}:
::: {.callout}
Un **modèle du domaine** n'est pas un **modèle de données** (\[ce dernier\] représente par définition des objets persistants stockés quelque part).
:::
Il peut y avoir des concepts dans un domaine qui ne sont pas dans la base de données.
Considérez l'exemple de la carte de crédit utilisée pour payer, mais qui n'est jamais stockée pour des raisons de sécurité.
Avec seulement un modèle de données, cette classe conceptuelle ne serait jamais modélisée.
Larman précise:
::: {.callout}
N'excluez donc pas une classe simplement parce que les spécifications n'indiquent pas un besoin évident de mémoriser les informations la concernant (un critère courant pour la modélisation des données quand on conçoit des bases de données relationnelles, mais qui n'a pas cours en modélisation d'un domaine), ou parce que la classe conceptuelle ne possède pas d'attributs. Il est légal d'avoir une classe conceptuelle sans attribut, ou une classe conceptuelle qui joue un rôle exclusivement comportemental dans le domaine.
:::
Vous pouvez aussi lire [cette question](https://stackoverflow.com/q/3507671/1168342) {{< fa brands stack-overflow >}}.
## Exercices
::: {#exr-MDD-trouver-classes-conceptuelles-catégorie}
### Trouver des classes conceptuelles par catégorie
À partir du [cas d'utilisation _Réserver un livre de la bibliothèque_](#sec-CU_Réserver_livre), trouvez des classes conceptuelles candidates en utilisant une liste de catégories de classes.
Vous pouvez remplir un tableau comme ceci:
| [**Catégorie de classes conceptuelles**](#sec-categoriesClasses) | **Classes candidates selon le cas d'utilisation** |
|:----------- |:----------- |
|Transaction d'affaires (métier) | _Réservation_ (Ceci est un exemple.) |
| (Continuez avec d'autres catégories.) | |
| (Certaines catégories ne s'appliqueront pas.) | |
| | (Certaines classes candidates seront découvertes par plusieurs catégories.) |
| | |
| | |
| | |
| | |
: {tbl-colwidths="[40,60]"}
:::
<!-- ::: {.solution}
**Catégorie de classe conceptuelle** | **Classes candidates selon le cas d'utilisation**
:----------|:----------
Transactions d'entreprise | Réservation
Rôles des personnes, organisation | Membre, Bibliothèque
Produit ou service lié à une transaction ou une ligne de transaction | Livre, Exemplaire
Lieu de la transaction | Bibliothèque
Objets physiques | Livre, Exemplaire
Descriptions d'objets (**voir sec. 9.13!**) | Livre (décrit la classe Exemplaire dont les objets peuvent tous être empruntés)
Catalogue | CatalogueLivre
::: -->
::: {#exr-MDD-trouver-classes-conceptuelles-noms}
### Classes conceptuelles trouvées à l'aide de groupes nominaux
Cette fois-ci, utilisez les groupes nominaux pour trouver des classes conceptuelles candidates.
Commencez par souligner ou par mettre en surbrillance les noms et les groupes nominaux dans le [cas d'utilisation _Réserver un livre de la bibliothèque_](#sec-CU_Réserver_livre).
Les groupes nominaux peuvent être des classes ou des attributs, ou peuvent ne pas s'appliquer du tout.
Faites une liste de classes conceptuelles candidates (sans doublons).
:::
<!-- ::: {.solution}
Bibliothèque \
Liste de livres \
Membre \
Nom \
Reservation \
Livre \
Titre \
Auteur \
ISBN \
Maison d'édition \
Numéro de l'édition \
Année \
Exemplaires \
Nombres \
Code \
Disponibilité \
Réservation \
Numéro de confirmation \
Nom du membre \
Code de l'exemplaire
::: -->
::: {#exr-MDD-comparer-classes-candidates}
### Comparaison des approches
Comparez la liste des classes trouvées dans l'@exr-MDD-trouver-classes-conceptuelles-noms avec les classes trouvées dans l'@exr-MDD-trouver-classes-conceptuelles-catégorie.
Quelles sont les différences?
:::
{{< include _callout_conseils_diagrammes.qmd >}}
::: {#exr-MDD-diagramme}
### Diagramme de classes conceptuelles
À partir du [cas d'utilisation _Réserver un livre de la bibliothèque_](#sec-CU_Réserver_livre), esquissez le modèle du domaine correspondant au domaine de l'application (cela comprend des **classes**, des **attributs** et des **associations**).
1. Considérez les classes candidates provenant de l'@exr-MDD-trouver-classes-conceptuelles-catégorie et de l'@exr-MDD-trouver-classes-conceptuelles-noms.
1. Notez que les classes candidates dénichées ne sont pas toujours importantes.
Certains concepts sont des attributs.
D'autres (surtout avec l'approche linguistique) n'ont rien à voir avec le problème du domaine.
Vous devez appliquer les directives vues dans le chapitre 9\ {{< fa solid book >}}.
1. Faites attention à bien modéliser la classe de "description" dans ce problème.
1. Tout attribut doit avoir un type.
1. Limitez-vous à des associations "mémorisables" dans le contexte de l'application du logiciel (ne pas faire des associations hors de la portée du cas d'utilisation).
1. Vérifiez les cardinalités.
1. Vérifiez les verbes sur les associations ainsi que le sens de lecture.
:::
::: {#exr-MDD-retroingenierie-discord}
### Création du MDD du logiciel Discord par rétro-ingénierie
Par rétro-ingénierie, réalisez le modèle du domaine pour une fonctionnalité du logiciel Discord.
1. Connectez-vous au logiciel Discord. Si vous n'avez pas de compte Discord, vous pouvez en créer un temporairement. Sur le [site web de Discord](https://discord.com/), cliquez sur "Ouvrir Discord dans ton navigateur".
1. Dans l'application Discord, créez un nouveau serveur et envoyez un message qui contient un fichier et du texte dans un salon textuel.
1. À l'aide de la liste de catégories de classes conceptuelles, proposez les classes conceptuelles qui sont nécessaires pour réaliser la fonctionnalité de l'étape précédente.
:::: {.callout-note collapse="true" icon="false"}
## Voici une solution
**Catégorie** | **Classes conceptuelles**
:----------|:----------
**Transactions d'affaires** | *Message*
**Rôle des personnes liées à la transaction** | *Utilisateur*
**Lieu de la transaction, lieu du service** | *Salon textuel*, *Salon*
**Conteneurs** | *Serveur*, *Profil*, *Fichier*
::::
4. Proposez les attributs de chaque classe conceptuelle qui sont nécessaires pour réaliser la fonctionnalité.
:::: {.callout-note collapse="true" icon="false"}
## Voici une solution
Voici une solution possible qui est cohérente avec l'étape précédente:
```{.plantuml genurl="true" #fig-mdd-retroingenierie-discord-attributs caption="Attributs des classes conceptuelles proposées dans l'exercice."}
@startuml
!include ecriture.pumlinclude
scale 1
hide empty members
class Message {
contenu : String
horodatage : DateHeure
}
class Utilisateur {
courriel : String
nomUtilisateur : String
nomAffichage : String
}
class Salon {
nom : String
}
class SalonTextuel {
sujet : String
}
class Serveur {
nom : String
}
class Profil {
avatar : File
}
class Fichier {
url : String
}
@enduml
```
::::
5. Proposez les associations entre les classes conceptuelles ainsi que leurs cardinalités.
:::: {.callout-note collapse="true" icon="false"}
## Voici une solution
Voici une solution possible qui est cohérente avec l'étape précédente:
```{.plantuml genurl="true" #fig-mdd-retroingenierie-discord-associations caption="Associations et cardinalités des classes conceptuelles proposées dans l'exercice."}
@startuml
!include ecriture.pumlinclude
scale 1
hide empty members
Utilisateur "1" -- "*" Message : Rédige >
SalonTextuel "1" -- "*" Message : Publie >
Profil "1" -left- "1" Utilisateur : Représente >
Utilisateur "1..*" -- "*" Serveur : Est-membre-de >
Utilisateur "1" -- "*" Serveur : Est-propriétaire-de >
Serveur "1" -- "*" SalonTextuel : Héberge >
Message "1" -right- "*" Fichier : < Est-joint-à
Utilisateur "1..*" -- "*" Salon : Est-membre-de >
class Message {
contenu : String
horodatage : DateHeure
}
class Utilisateur {
courriel : String
nomUtilisateur : String
nomAffichage : String
}
class Salon {
nom : String
}
class SalonTextuel extends Salon {
sujet : String
}
class Serveur {
nom : String
}
class Profil {
avatar : File
}
class Fichier {
url : String
}
@enduml
```
::::
:::
::: {#exr-MDD-associations-riches}
### Utiliser des verbes plus riches pour décrire les associations
La @fig-mdd_youtube présente une modèle du domaine partiel pour le logiciel YouTube.
Toutefois, les associations du MDD utilisent des verbes ternes qui n'aident pas à comprendre le domaine.
Remplacez les verbes des associations par des verbes plus riches.
Vous pouvez inverser le sens des associations.
```{.plantuml genurl="true" #fig-mdd_youtube caption="Modèle du domaine partiel pour le logiciel YouTube."}
@startuml
!include ecriture.pumlinclude
scale 1
hide empty members
Utilisateur "1" -- "*" Chaîne : Possède >
Chaîne "1" -- "*" Vidéo : Contient >
Utilisateur "1" -- "*" ListeDeLecture : Possède >
ListeDeLecture "*" -- "*" Vidéo : Contient >
Vidéo "1" -- "*" SousTitre : A >
Vidéo "1" -- "1" Statistique : Possède >
class Vidéo {
titre : String
description : String
url : String
}
class Utilisateur {
nomUtilisateur : String
courriel : String
}
class ListeDeLecture {
nom : String
description : String
visibilite : String
}
class Chaîne {
description : String
}
class SousTitre {
langue : String
}
class Statistique {
visionnements : int
dureeVisionnement : float
impressions : int
}
@enduml
```
:::: {.callout-note collapse="true" icon="false"}
## Voici une solution
```{.plantuml genurl="true" #fig-mdd_youtube_ameliore caption="Modèle du domaine partiel pour le logiciel YouTube avec des verbes d'association plus riches."}
@startuml
!include ecriture.pumlinclude
scale 1
hide empty members
Utilisateur "1" -- "*" Chaîne : Gère >
Chaîne "1" -- "*" Vidéo : Publie >
Utilisateur "1" -- "*" ListeDeLecture : Administre >
ListeDeLecture "*" -- "*" Vidéo : Enregistre >
Vidéo "1" -- "*" SousTitre : Est-plus-accessible-avec >
Statistique "1" -- "1" Vidéo : Mesure-visualisation-de >
class Vidéo {
titre : String
description : String
url : String
}
class Utilisateur {
nomUtilisateur : String
courriel : String
}
class ListeDeLecture {
nom : String
description : String
visibilite : String
}
class Chaîne {
description : String
}
class SousTitre {
langue : String
}
class Statistique {
visionnements : int
dureeVisionnement : float
impressions : int
}
@enduml
```
::::
:::