Object Constraint Language
OCL
PARTIE 1
1
• Le diagramme de classes
• Le rôle
• Le problème
• Solutions potentielles ?
2
Système de gestion des emprunts et des
retours dans une bibliothèque
• La bibliothèque gère des livres et des revues. Un livre est caractérisé par son titre,
son code ISBN. Un numéro de revue est caractérisé par le titre de la revue, un
numéro de volume et sa date de parution. Chaque exemplaire d’une ressource
est caractérisé par un code barre au sein de la bibliothèque.
• Un utilisateur ne peut emprunter un ouvrage que si la caution qui lui reste sur
son compte est supérieure à la caution de l’ouvrage. La durée de l’emprunt est
fixée à 15 jours.
• On ne peut pas emprunter plus d’un exemplaire d’une même ressource, ni
emprunter une nouvelle ressource si on est en retard pour rendre une ressource.
• L’emplacement de stockage d’un ouvrage dans la bibliothèque est représenté par
un numéro de travée, un numéro d’étagère dans la travée, et un niveau.
• Différentes ressources peuvent être rangées au même emplacement, mais tous
les exemplaires d’une même ressource sont stockés au même endroit.
3
4
Motivations
• Le diagramme de classes
• Décrit la structure de notre système : objets + relations
+
• Exprimer des contraintes
• Type des attributs
• Multiplicités des associations
A priori, TOUS les diagrammes d’objets qui respectent ces deux
types de contraintes, seraient des INSTANCES VALIDES du diagramme
de classes.
5
Contraintes sur les attributs
• un compte doit avoir un solde toujours
positif ;
• une banque gère plusieurs comptes ;
• une banque possède plusieurs clients.
• une personne peut être cliente de
plusieurs banques ;
• un client peut posséder plusieurs
comptes ;
• un client d'une banque possède au moins
un compte dans cette banque ;
• un compte appartient forcément à un
client ;
6
Problème de cohérence
Diagramme d’objets cohérent avec :
• le diagramme de classes initial
• la spécification du problème
7
Problème de cohérence
• un client d'une
banque possède au
moins un compte
Diagramme d’objets : dans cette banque ;
• valide vis-à-vis du diagramme de classes • un compte appartient
• NE respectant pas la spécification du problème forcément à un
client ;
8
Motivations
• Le diagramme de classes
• Permet d’exprimer quelques contraintes (type d’attributs,
multiplicité)
• Ne permet pas d'exprimer tout ce qui est défini dans la
spécification
• Valeurs autorisées des attributs
• Conditions sur les associations
• Relations entre les attributs ou entre les associations
Il ne vous raconte pas toute l’histoire !
9
Contraintes sur les attributs
• Quelles sont les contraintes possibles sur les attributs ?
10
Contraintes sur les attributs
11
Contraintes sur les associations
12
Solutions potentielles
• Expression des contraintes liées au diagramme
• On a besoin de spécifier des informations
supplémentaires/contraintes importantes qui n'ont pas pu l‘être
avec les éléments de modélisation d'UML
• Solutions
• Texte avec le diagramme : + Compréhensible/- ambiguïté !!
difficulté pour les contraintes complexes
• Notes dans le diagramme
• OCL : langage de contraintes formel associé à UML
13
• Contrainte ? Invariant ?
• Quelle est la spécificité d’une contrainte ?
• Des exemples de contraintes ?
14
Contraintes, invariants
• Contrainte sémantique du Exemples
modèle • « Le solde du compte doit être
• Condition à respecter toujours positif ».
• Restriction
• « Un livre ne peut pas être
• Assertion emprunté par deux personnes
différentes en même temps » .
• « Une personne ne peut pas
être professeur et chargée de
cours en même temps ». 15
Contraintes, invariants
• Doit être VRAI à tout instant de Objectif
l’éxécution
• Respect de la spécification
• Contraintes de
• Attachée à n'importe quel sémantique
élément de modèle. • Ce n’est pas une
implémentation !
• Exprimé dans un langage
textuel qui peut être naturel ou
formel.
16
OCL = Object Constraint Language
OCL (Object Constraint Language)
• langage formel basé sur la logique mathématique
• expression des contraintes sémantiques
• spécifier des contraintes d’état (sur le comportement des éléments du diag). 17
Contraintes sur les attributs
context Compte
inv : solde > 0 Attribut
context Compte ::
débiter(somme : int)
Opération
pre : somme > 0
post : solde = solde@pre -
somme
context Compte Association
inv : [Link] ->
includes (propriétaire) 18
Avantages OCL
• OCL est une technologie mature
• fait officiellement partie de UML (adapté au diagramme
de classes)
• Supporté par plusieurs outils (Rational Rose, AgroUML,
Eclipse, Poseidon, Entreprise Architect)
• + simple à mettre en œuvre, compréhensible, formel mais
simple d'accès
un juste milieu entre le langage naturel et un langage très technique
19
OCL vs. langage naturel
• Langage naturel
+ accessible
- ambigu, imprécis
• OCL (langage formel)
+ précis, non-ambigu
+ interprétable par des outils
20
OCL vs. langage de programmation
• Langage de programmation
• faible niveau d’abstraction
• mode opérationnel (COMMENT)
• OCL (langage formel)
• abstrait
• mode descriptif (QUOI)
21
OCL
1) Typologie des contraintes
2) Types de base et opérations
3) Accès aux objets et navigation
4) Collections
5) Conception par contrats pour opérations
22
23
Context
Inv
Pre/Post
body/result
Init/derive
Let..in/def
24
Contexte
• C’est l’élément de modèle auquel on associe la contrainte.
• Syntaxe
context <élément>
<élément> peut être une classe, une opération, etc.
25
Exemples
• context Compte
• s'applique a la classe Compte, c'est-a-dire à toutes les instances de cette classe
• context Compte::getSolde() : Real
• s'applique à la méthode getSolde()
• context Compte::crediter(somme : Real)
• s'applique à la méthode crediter
• context Compte::solde : Real
• s'applique à l'attribut solde
26
Invariants (inv)
• Exprime une contrainte sur un objet, ou un groupe d'objets, qui doit
être respectée en permanence.
• Syntaxe
inv : <expr_log>
<expression_logique> est une expression logique qui doit toujours être
vraie.
• Exemples
context Compte
inv: solde > 0 -- solde d'un compte doit toujours être positif
27
C: L‘âge doit être compris entre 0 et 140 ans 28
Exemples
context Personne
inv: (age <= 140) and (age >=0) -- l‘âge est compris entre 0 et 140 ans
context Personne
inv : ([Link] <= 140) and ([Link] >=0)
context p:Personne
inv borneAge: ([Link] <= 140) and ([Link] >=0)
• . permet d'accéder a une caractéristique d'un objet (méthode, attribut,
terminaison d'association)
• self objet désigné par le contexte
29
Context
Inv
Pre/Post
body/result
Init/derive
Let..in/def
30
Précondition/Postcondition> OPERATIONS
• Spécifier une contrainte qui doit être vérifiée
• AVANT l'appel d'une opération Précondition
• APRES l'appel d'une opération Postcondition
• Syntaxe
• Précondition
pre : <expr_log>
• Postcondition
post : <expr_log>
<expr_log> est une expression logique qui doit toujours être vraie.
31
Précondition/Postcondition
• La méthode « setAge »
• met à jour l’âge d’une personne
• prend comme argument l’âge « a » de type entier
• En OCL
o Quelles sont les préconditions ?
o Quelles sont les postconditions ?
32
Exemple
context Personne::setAge(a :entier)
pre : (a <= 140) and (a >=0) and (a >= age)
post : age = a
attribut
33
Postcondition
• Postcondition : deux éléments particuliers sont utilisables
• <nom_attribut>@pre : désigne la valeur de l'attribut avant
l'appel de l'opération.
• l'attribut result : la valeur retournée par l’opération ;
context Compte::débiter(somme : Real)
pre : somme > 0
post : solde = solde@pre - somme
34
Résultat d’une méthode (result)
• Représente la valeur de retour de cette opération
• On peut utiliser « result » pour définir une contrainte sur la
valeur renvoyée par l’opération
context Compte::getSolde() : Real
post : result = solde
35
Précondition/Postcondition : ATTENTION
• On ne décrit pas comment l'opération est réalisée
mais des contraintes sur l'état AVANT et APRES son
exécution.
• Spécifier la sémantique d'une opération : ce qu'elle
fait et non pas comment elle le fait
• post concerne les effets de bord (modification d'un
argument, d'un autre membre de la classe, etc.)
36
Comportement d’une opération (body)
• définir directement le comportement d’une opération.
• Syntaxe
body : <requête>
<requête> est une expression qui retourne un résultat dont le type doit être
compatible avec le type du résultat de l'opération désignée par le contexte.
37
Exemple 1
context Rectangle::area() : Integer
-- Définition du calcul de l'aire via 'body'
body : width * height
-- Postcondition pour s'assurer que le résultat
de l'opération est correct
Post : result = width * height
38
Exemple 2
context Compte::getSolde(): Real
body : solde
context Compte::getSolde() : Real
post : result = solde
39
Context
Inv
Pre/Post
body/result
Init/derive
Let..in/def
40
Valeur initiale d’un attribut (init)
• Initialiser la valeur d’un attribut ou d’une terminaison d’association.
• Syntaxe
init : <requête>
• Exemple
context Personne::age : entier
init : 0
41
Valeur initiale d’un attribut (init)
• Initialement, une personne n’est pas mariée.
context Personne::marié : Boolean
init : false
• A la création d'un compte, 50dt offerts par la banque
context Compte::solde : Real
init : 50
42
Valeur dérivée d’un attribut (derive)
• Définir des attributs ou des associations dérivées.
• La valeur de tels éléments est toujours déterminée en fonctions
d’autres éléments du diagramme.
• derive permet de préciser comment la valeur de ce type d'élément
évolue.
• Syntaxe
derive : <requête>
43
Exemple
• L'âge d’une personne est la différence entre la date courante et la
date de naissance de la personne
context Personne::age : Integer
derive : Date::current() - date_de_naissance
44
Init/derive
• La contrainte init
• ne s'applique qu'au moment de la création d'une instance
précisée par le contexte de la contrainte. Ensuite, la valeur
de l'élément peut changer indépendamment de la
contrainte init.
• La contrainte derive
• impose une contrainte perpétuelle : l'élément dérivé doit
toujours avoir la valeur imposée par l'expression de la
contrainte derive. 45
Définition de variables (let…in)
• Définir des variables pour simplifier l’écriture de certaines
expressions.
• Syntaxe
let variable : type = expression1 in expression2
Une nouvelle variable déclarée aura la valeur retournée par
<expression 1> dans toute l’<expression 2>.
Très utile quand une sous-expression est utilisée plusieurs fois dans
une expression.
46
Définition de variables (let…in)
Exemple
context Personne
inv : let montantImposable : Real = salaire*0.8
in
impot = montantImposable*45/100
47
Définition de variables et d’opérations (def)
• Définir des variables/opérations
• comme la séquence let…in MAIS utilisables dans plusieurs contraintes de la
classe
• Syntaxe
def variable : type = expression1
• <variable> peut correspondre à la déclaration d'un attribut ou d'une
méthode.
• <expression1> est une expression qui retourne un résultat dont le type
doit être compatible avec le type de l'attribut, ou de la méthode.
48
Définition de variables et d’opérations (def)
• Exemples
context Personne
def : montantImposable : Real = salaire*0.8
context Personne
def : ageCorrect(a :Real) : Boolean = (a>=0) and (a<=140)
context Personne
inv: ageCorrect(age) -- l’âge ne peut dépasser 140 ans
49
Context
Inv
Pre/Post
body/result
Init/derive
Let..in/def
50
51
Exercice
• Les salaires doivent être compris entre 1000dt et 4000dt.
context Poste
inv : ([Link]>=1000) AND ([Link]<=4000)
• La date de mariage est initialisée à 0.
context Mariage::date: Date
init : 0
• Un compte doit être toujours créditeur
context Compte
inv : solde>0
52
Exercice
• Produire les invariants, préconditions et postconditions possibles sur
la classe « Compte », sachant que le solde doit être toujours
strictement supérieur au « plancher ».
Compte
solde: Real
plancher: Real
Débiter (montant: Real)
Créditer (montant: Real)
53
Exercice
• Invariants
context Compte
inv : solde > plancher
• Méthode « créditer »
context Compte::créditer (montant:Real)
pre: montant > 0
post: solde = solde@pre + montant
• Méthode « débiter »
context Compte::débiter (montant:Real)
pre: (montant > 0) and (plancher <= solde – montant)
post: solde = solde@pre - montant
54
Object Constraint Language
OCL
PARTIE 2
55
OCL
1) Typologie des contraintes
2) Types de base et opérations
3) Accès aux objets et navigation
4) Collections
5) Conception par contrats pour opérations
56
Rappel
• UML ne permet pas de TOUT décrire => On a besoin de spécifier des informations
supplémentaires/contraintes importantes
• Contrainte sémantique du modèle
• Condition à respecter / Restriction / Assertion
• VRAI à tout instant de l’éxécution (pourquoi l’éxécution ?)
• Exemple : salle vs. capacité
• OCL (Object Constraint Language)
• Langage formel basé sur la logique mathématique
• Expression des contraintes sémantiques
• Respect de la spécification
• Mieux contraindre l’implémentation MAIS ce n’est pas une implémentation !
un juste milieu entre le langage naturel et un langage très technique
57
Tableau récapitulatif
Rôle Exemple
context • s'applique à toutes les instances de • context Compte
l’élément indiqué • context Compte::getSolde() : Real
inv • Exprime une contrainte sur un objet, context Compte
ou un groupe d'objets, qui doit être inv: solde > 0
TOUJOURS respectée
58
Tableau récapitulatif
Rôle Exemple
pre • Spécifier une contrainte qui doit être context Personne::setAge(a :entier)
vérifiée AVANT l'appel d'une opération pre : (a <= 140) and (a >=0) and (a
>= age)
post • Spécifier une contrainte qui doit être context Compte::débiter(somme :
vérifiée APRES l'appel d'une opération Real)
post : solde = solde@pre - somme
context Compte::getSolde() : Real
post : result = solde
59
Tableau récapitulatif
Rôle Exemple
result • faire référence au résultat d’une context Compte::getSolde() : Real
opération post : result = solde
body • Accéder directement au résultat d’une context Compte::getSolde() : Real
opération body : solde
== solde c’est un attribut
init • Initialiser la valeur d’un attribut ou context Personne::age : entier
d’une terminaison d’association init : 0
derive • Définir des attributs ou des associations context Personne::age : Integer
dérivées. La valeur en fonctions d’autres derive : Date::current() -
éléments du diagramme date_de_naissance
60
Tableau récapitulatif
Rôle Exemple
let…in • Définir des variables pour simplifier context Personne
l’écriture de certaines expressions inv : let montantImposable : Real =
salaire*0.8 in
impot = montantImposable*45/100
def • Définir des variables/opérations : context Personne
comme la séquence let…in MAIS def : montantImposable : Real =
utilisables dans plusieurs contraintes de salaire*0.8
la classe
61
62
Exemple (Opérateurs)
• Pour être marié, il faut avoir plus de 18 ans.
1) Reformuler un peu avec …
2) Identifier les éléments impliqués
• Contexte : Personne
• Attribut : marié (Booléen)
• Attribut : age (Integer)
3) Les solutions possibles
context Personne
inv : marié implies age >=18
63
Types de base et opérations
• Définir plusieurs contraintes pour un invariant, une pre ou postcondition :
• and « et logique » : l’invariant, pre ou postcondition est vrai si toutes
les expressions reliées par le and sont vraies
• or et xor
64
Types de base et opérations
• Certaines contraintes sont dépendantes d'autres contraintes
• if expr1 then expr2 else expr3 endif
Si l'expression expr1 est vraie alors expr2 doit être vraie sinon expr3 doit
être vraie
• Il n'existe pas de if … then sans la branche else
• Sinon, il faut utiliser « implies »
• expr1 implies expr2
Si l'expression expr1 est vraie, alors expr2 doit être vraie également.
Si expr1 est fausse, alors l'expression complète est vraie.
65
Exemple
• Une personne majeure doit avoir plus de 18 ans.
• Classe « Personne »
• Attribut « age »
• Attribut « majeur » de type boolean
context Personne
inv : if age >=18 then
majeur=vrai
else majeur=faux
endif
66
Exemple
• Une personne mariée est majeure
• Classe « Personne »
• Attribut « marié » de type boolean
• Attribut « majeur » de type boolean
context Personne
inv : marié implies majeur
67
Type énuméré
• Genre n’est PAS une CLASSE !!
68
Types de base et opérations
• Types énumérés
<nom_type_enuméré>::valeur
• Toutes les personnes sont des femmes.
• Classe « Personne »
• Attribut « genre » de type Genre
context Personne
inv : genre = Genre::femme
69
Type Collection
• Définir la notion d’ensemble
• Plusieurs sous-types du type abstrait Collection
• Set : ensemble non ordonné d‘éléments uniques (pas de doublons).
• OrderedSet : ensemble ordonné d‘éléments uniques (pas de doublons).
• Bag : collection non ordonnée d‘éléments identifiables (doublons possibles).
• Sequence : collection ordonnée d‘éléments identifiables (doublons possibles).
• Exemples
• { 1, 4, 3, 5 }
Set non ordonné/pas de doublons
• { 1, 3, 4, 5 }
OrderedSet ordonné/pas de doublons
• { 1, 1, 3, 4, 4, 5 }
Sequence ordonné/doublons
• { 1, 4, 1, 3, 5, 4 }
Bag non ordonné/doublons 70
71
Exercice 1
1) Un compte n’a jamais un solde nul (2 manières)
2) Toutes les femmes mariées doivent être âgées de plus que 18 ans.
3) Une personne mariée doit avoir plus que 18 ans, n’est pas au
chômage et son revenu est supérieur à 500dt.
4) Remplacer « personne » par « homme »,
dans la contrainte précédente.
72
Exercice 1
1) Un compte n’a jamais un solde nul (2 manières)
context Compte
inv : (solde > 0)
context Compte
inv : not (solde <= 0)
73
2) Toutes les femmes mariées doivent être âgées de plus que 18 ans
context Personne inv :
((genre = Genre::femme) and (marié = true)) implies
(age >= 18))
74
3) Une personne mariée doit avoir plus que 18 ans, n’est pas au chômage et son revenu est
strictement supérieur à 500dt.
• Solution 1
context Personne
def rev : Real = revenu()
context Personne inv :
((marié = vrai)) implies
(age >= 18) and (chomeur=false) and (rev > 500)
• Solution 2
context Personne inv :
let rev : Real = revenu() in
(((marié = vrai)) implies
(age >= 18) and (chomeur=false) and (rev > 500))
75
Exercice 1
3) Un homme marié doit avoir plus que 18 ans, n’est pas au chômage et son revenu est
strictement supérieur à 500dt.
• Solution 1
context Personne
def rev : Real = revenu()
context Personne inv :
((marié = vrai) and (genre = Genre::homme)) implies
(age >= 18) and (chomeur=false) and (rev > 500)
• Solution 2
context Personne inv :
let rev : Real = revenu() in
(((marié = vrai) and (genre = Genre::homme)) implies
(age >= 18) and (chomeur=false) and (rev > 500))
76
Exercice 2
• L’âge d’une personne, ayant un revenu, ne peut pas être inférieur à 18
ans et son revenu ne doit pas dépasser 5000.
context Personne:: revenu(): Integer
pre: [Link] >= 18
post: result < 5000
77
Exercice 3
• Ajouter l’attribut simple (non dérivé), appelé « cartevermeil » à la
classe « Personne », de type Boolean.
• Une personne a droit à la carte vermeil si c'est une femme de plus de
60 ans ou un homme de plus de 65 ans.
78
Exercice 3
context Personne inv :
carteVermeil =
(((genre = Genre::homme) and (age >= 65))
or
((genre = Genre::femme) and (age >= 60)))
79