-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathContrats.qmd
173 lines (116 loc) · 10.5 KB
/
Contrats.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
# Contrats d'opération {#sec-contrats}
Un contrat d'opération est un document décrivant les modifications permanentes à l'état du système après l'exécution d'une opération système.
Les modifications permanentes à l'état du système comprennent:
- la création ou la destruction d'une instance;
- la modification d'un attribut d'une instance;
- la création ou la suppression d'associations entre les instances.
Les contrats d'opération sont présentés sous forme de postconditions utilisant le vocabulaire du modèle du domaine.
::: {.callout-important}
Le MDD est un modèle de la vraie vie.
Il y a des classes conceptuelles (comme Vente), mais aussi des *instances* de ces classes.
Dans un magasin, pour chaque nouvelle vente, on imagine une nouvelle instance de la classe Vente.
S'il y a eu 72 clientes et clients qui ont acheté des choses dans un magasin dans une journée, on imagine 72 instances de Vente, une pour chaque cliente ou client.
:::
Sur la @fig-ContratExempleCreerNouvelleVente, l'opération système `créerNouvelleVente()` provient d'un diagramme de séquence système lié au cas d'utilisation *Traiter une Vente*.
Elle correspond au moment où le caissier ou la caissière démarre une nouvelle vente pour un client ou une cliente.
Avant l'exécution de cette opération, l'instance de la classe Vente indiquée dans le modèle du domaine n'existe pas.
Cependant, après l'exécution de l'opération système, l'instance de Vente devrait exister.
Le contrat d'opération spécifie ce fait dans une postcondition (avec la voix passive au passé composé en français): "une instance *v* de Vente a été créée".
Un contrat d'opération permet de spécifier tous les changements dans le MDD qui doivent avoir lieu lors de l'opération système. Les postconditions du contrat saisissent l'évolution du MDD.
![Pendant l'opération système `créerNouvelleVente`, une instance de Vente doit être créée. Le contrat d'opération le spécifie dans une postcondition : une instance *v* de Vente a été créée.](images/Contrats-survol_export.svg){#fig-ContratExempleCreerNouvelleVente}
## Les contrats en bref
Les contrats d'opération sont le sujet du chapitre 11\ {{< fa solid book >}}\ [-@craig_uml_2005].
Voici les points importants pour la méthodologie enseignée dans le présent manuel:
- Un contrat d'opération correspond à une opération système provenant d'un DSS.
- On fait des contrats surtout pour les opérations système ayant une certaine complexité.
- Une postcondition décrit les modifications de l'état des objets dans le modèle du domaine après une opération système.
- Le vocabulaire pour les postconditions provient du modèle du domaine. Il s'agit des noms de classes, d'attributs et d'associations qu'on trouve dans le MDD.
- Chaque postcondition doit avoir la bonne forme:
- création (ou suppression) d'instances;
- modification des valeurs des attributs;
- formation (ou rupture) d'associations.
- On ne spécifie pas les préconditions dans les contrats (Larman ne donne pas beaucoup de directives claires à ce propos).
- Il ne faut pas confondre les postconditions d'un contrat d'opération et les postconditions d'un cas d'utilisation. Ce sont deux choses différentes.
- Quand on rédige les contrats, il est normal de découvrir dans le modèle du domaine des incohérences ou des éléments manquants.
Il faut les corriger (il faut donc changer le MDD), car cela fait partie d'un processus itératif et évolutif.
## La rédaction des postconditions
Voici quelques consignes pour la rédaction des postconditions dans les contrats d'opération.
**1. Les postconditions doivent décrire les effets de l'opération sur l'état du système.**
Cela inclut les modifications apportées aux objets, la création ou la suppression d'objets, et les changements de relations entre les objets.
Une postcondition doit donc décrire un des changements suivants:
- création (ou suppression) d'instances;
- modification des valeurs des attributs;
- formation (ou rupture) d'associations.
Si une opération n'effectue aucun de ces changements, comme une opération de lecture ou d'affichage d'information, il n'y a donc pas de postcondition à indiquer. Il suffit alors d'écrire "Aucune" dans la section des postconditions.
**2. Exprimez les postconditions au passé**
Il est nécessaire de décrire les changements dans l'état du système après l'exécution de l'opération.
Ce ne sont pas ceux qui ont lieu ou qui doivent avoir lieu.
L'utilisation d'expressions au passé telles que: "a été créé", "a été associé", "est devenu" sont donc fréquentes.
**3. Rédigez des phrases courtes et concises**
Il est important de formuler des phrases courtes et concises, en se concentrant sur les changements essentiels de l'état du système sans ajouter d’informations superflues.
Cela rend les postconditions plus faciles à vérifier lors des tests et de la validation des exigences.
Chaque postcondition doit être traitée comme une assertion distincte pour assurer une meilleure clarté et précision.
**4. Utiliser le vocabulaire du modèle du domaine dans les postconditions**
Cela implique de parler des instances de classes conceptuelles, de leurs attributs et des associations entre ces classes.
Par exemple, si le MDD possède une classe "Client", il ne faut pas utiliser le terme "Utilisateur" pour représenter cette classe dans une postcondition, même si un client pourrait être un utilisateur.
Il est important de réutiliser les termes du MDD pour assurer la cohérence entre les différents documents de conception.
Les postconditions seront utilisées par les développeurs pour concevoir et implémenter le système.
::: {.callout-tip}
Le but est de garder un faible écart entre le modèle du monde réel (classes conceptuelles dans le MDD) et les solutions en programmation orientée objet (classes logicielles).
:::
**5. Utiliser des noms d'instances pour simplifier les références**
Utiliser des noms d'instances dans les postconditions est utile pour simplifier les références et rendre les postconditions plus claires et précises.
Par exemple, voici une première condition d'une opération:
- *Une instance lar de LigneArticles a été créée.*
Le nom de l’instance lar est destiné à simplifier les références à cette nouvelle instance dans les autres postconditions.
Les autres conditions peuvent donc être rédigées comme suit:
- *lar.quantité est devenu la valeur du paramètre quantité.*
- *lar a été associé à la Vente en cours.*
En utilisant un nom d'instance spécifique, il devient facile de suivre et de comprendre les modifications apportées à cet objet particulier. Cela élimine les ambiguïtés sur quel objet est modifié.
## Exemple: Contrats d'opération pour Attaquer un pays {#sec-contrat_exemple}
Voir la @fig-MDD-risk-objets pour les changements dans les objets du modèle du domaine correspondant aux postconditions.
### Attaquer un pays {.unnumbered .unlisted}
#### Opération: `démarrerAttaque(paysAttaquant:String, paysDéfenseur:String)` {.unnumbered .unlisted}
#### Postconditions: {.unnumbered .unlisted}
- Une nouvelle instance *a* de Attaque a été créée.
- *a* a été associée au Pays correspondant à paysAttaquant.
- *a* a été associée au Pays correspondant à paysDéfenseur.
#### Opération: `annoncerAttaque(nbRégimentsAttaquant:int)` {.unnumbered .unlisted}
#### Postcondition: {.unnumbered .unlisted}
- a.nbAttaquant est devenu nbRégimentsAttaquant.
#### Opération: `annoncerDéfense(nbRégimentsDéfendant:int)` {.unnumbered .unlisted}
#### Postconditions: {.unnumbered .unlisted}
- a.nbDéfenseur est devenu nbRégimentsDéfendant.
- L'attribut valeur des d1 à d5 est devenu un nombre entier aléatoire entre 1 et 6.
- Occupation.nbRégiments est ajusté selon le résultat des valeurs correspondant à paysAttaquant.
- Occupation.nbRégiments est ajusté selon le résultat des valeurs correspondant à paysDéfenseur.
::: {.callout-important}
Les règles pour la résolution d'une attaque dans le jeu Risk sont complexes.
Pour faire un exemple plus facile à comprendre, on en fait abstraction.
:::
<!-- Draw.io svg contient du texte en SVG qui ne se présente pas bien lors de la conversion vers PDF (on obtien "Text is not SVG - cannot display"). Alors, on exporte manuellement une version du SVG ayant du texte compatible (tout en gardant l'original). Cela n'est pas idéal, mais c'est une solution. Voir https://www.diagrams.net/doc/faq/svg-export-text-problems et l'option "convert labels to SVG" -->
![Les postconditions décrivent la manipulation d'objets dans un MDD (la partie inférieure ici est un diagramme d'objets).](images/MDD-Risk-contrats_export.svg){#fig-MDD-risk-objets}
## Feuille de référence
Pour faire des contrats, voici une démarche générale:
1. Faire un contrat pour chaque opération système.
1. Porter une attention à sa signature (les arguments et leur type).
1. Rappeler les formes de postconditions:
a) créer/supprimer instances;
a) former/briser associations;
a) modifier attributs.
1. Utiliser *le vocabulaire du modèle du domaine* dans les postconditions.
Ça veut dire qu'il faut parler d'instances de classes conceptuelles, de leurs attributs et des associations entre ces classes.
1. Ne pas créer une instance de classe qui existe déjà, par exemple un produit (connu) dans un magasin, un acteur (connu) qui se connecte au système, ou, dans l'exemple de Risk, un Pays (voir la partie inférieure de la @fig-MDD-risk-objets).
1. Ne rien oublier. Marquer le MDD ou dessiner un diagramme d'objets, comme à la partie inférieure de la @fig-MDD-risk-objets si nécessaire.
## Exercices
::: {#exr-contrat_Terminer_attaque}
### `terminerAttaque()`
Rédigez le contrat d'opération pour `terminerAttaque()`.
Il faut considérer les règles d'attaque (voir [la page de wikiHow](https://fr.wikihow.com/jouer-%C3%A0-Risk)) et les cas où une attaque a réussi, c'est-à-dire que le `paysDéfenseur` change de Joueur (celui du `paysAttaquant`).
Suivez les exemples de contrats d'opération présentés à la @sec-contrat_exemple.
:::
::: {#exr-contrats-Traiter-vente}
### Contrats d'opération pour *Traiter une vente*
Rédigez **un contrat d'opération pour chacune des opérations système** dans le DSS (et qui doit être cohérent avec le MDD) de la @sec-DSS_traiter_vente.
Suivez les exemples de contrats d'opération à la @sec-contrat_exemple.
:::