Chapitre 4 OCL: Object Constraint Language
Responsable de cours : Sahar GHRAB
Année universitaire : 2023/2024
1
Motivations
• Dans le métamodèle UML, une opération n’est définie que par
son nom, ses paramètres et les exceptions qu’elle émet.
• En utilisant uniquement UML, il n’est pas possible d’exprimer
toutes les contraintes que l’on souhaiterait.
• Exemple: il n’est pas possible de dire que l’attribut solde d’une
ClasseBancaire ne doit pas être inférieur à 1000 dt et doit être un
nombre positif.
Une expression OCL est rattaché à un contexte
qui est un élément de modèle UML et peut
être évaluée afin de retourner une valeur.
Expression OCL 1: contexte: classe CompteBancaire
attribut: valeur de l’attribut solde
Expression OCL 2: contexte: classe Personne
vérifier qu’une personne dispose
2
ou non d’un compteBancaire
Motivations
• Pour une bibliothèque particulière on peut vouloir demander :
– Livres possédés par la bibliothèque ? Combien y en a-t-il ?
– Auteurs dont au moins un titre est possédé par la bibliothèque ?
– Titres dans la bibliothèque écrits par Martin Fowler ?
– Nombre de pages du plus petit ouvrage ?
– Nombre moyen de pages des ouvrages ?
– Ouvrages de plus 100 pages écrits par au moins trois auteurs ?
3
Historique
• OCL s’inspire de Syntropy (méthode basée sur
une combinaison d’OMT (Object Modeling
Technique) et d’un sous-ensemble de Z).
• A l’origine, OCL a été développé en 1997 par
Jos Warmer (IBM), sur les bases du langage
IBEL (Integrated Business Engineering
Language). Il a été formellement intégré à
UML 1.1 en 1999
4
OCL, c’est quoi?
• OCL (Object Constraint Language) permet de définir des
contraintes sur les opérations afin de préciser leur
sémantique et d’exprimer des requêtes de navigation dans
les langages de transformation.
• Une expression OCL n’entraîne aucun changement dans le
modèle auquel elle est rattachée.
• Une contrainte OCL est une expression dont l’évaluation
doit retourner vrai ou faux. L’évaluation de cette contrainte
permet de savoir si la contrainte est vérifiée (vérifier aussi
la conformité des types qu’elle utilise).
• L’objectif d’OCL est d’être indépendant de toute plateforme
d’exécution.
5
OCL et diagrammes UML
• OCL permet d’exprimer des contraintes sur tous les
éléments des modèles UML.
• OCL peut être utilisé sur différents diagrammes d’UML:
– diagramme de classe :
• définir des préconditions, postconditions et invariants : Stéréotypes
prédéfinis : «precondition», «postcondition» et «invariant»
• caractérisation d’un attribut dérivé (p.ex. le salaire est fonction de l’âge)
• spécifier la valeur initiale d’un attribut (p.ex. l’attribut salaire d’un
employé)
• pécifier le code d’une opération (p.ex. le salaire annuel est 12 fois le
salaire mensuel)
– diagramme d’état :
• spécifier une garde sur une transition
• exprimer une expression dans une activité (affectation, etc.) ...
– diagramme de séquence :
• spécifier une garde sur un envoi de message
6
OCL et diagrammes UML
• Une expression OCL doit être doit être
rattaché à un contexte qui doit être
directement relié à un modèle UML.
Si le contexte est une classe UML: la contrainte OCL
est évaluée sur toutes les instances de la classe
UML.
Si le contexte est une propriété opération ou
attribut) d’une classe: la contrainte OCL est évaluée
sur toutes les instances de la classe UML mais porte
uniquement sur la propriété identifié.
7
OCL et diagrammes UML
• Contexte:
– Si le contexte est une classe UML: la contrainte OCL est évaluée sur toutes les
instances de la classe UML.
– Si le contexte est une propriété opération ou attribut) d’une classe: la
contrainte OCL est évaluée sur toutes les instances de la classe UML mais porte
uniquement sur la propriété identifié.
• Invariant(inv) : propriété définie sur une classe qui doit toujours être vraie,
de la création à la disparition d’un objet. Un invariant lie les requêtes d’une
classe (état externe).
• Précondition (pre): propriété sur une méthode qui :
– doit être vérifiée par l’appelant pour que l’appel à cette méthode soit possible ;
– peut donc être supposée vraie dans le code de la méthode
• Postcondition (post): propriété sur une méthode qui définit l’effet de la
méthode, c’est-à-dire :
– spécification de ce que doit écrire le programmeur de la méthode ;
– caractérisation du résultat que l’appelant obtiendra.
– Le mot-clé result permet d’identifier la valeur de retour de l’opération.
8
OCL et diagrammes UML
OCL et métamodélisation: préciser la sémantique statique d’un modèle
Les langages formels traditionnels (e.g.
Z) requièrent de la part des utilisateurs
une bonne compréhension des
fondements mathématiques.
Object Constraint Language (OCL) a été
développé dans le but d’être :
formel, précis et non ambigu
utilisable par un large nombre
d’utilisateurs, I un langage de
spécification (et non de
programmation!),
supporté par des outils
9
OCL et diagrammes UML
Le mot clé self permet de référencer
l’élément sur lequel porte
l’expression OCL
10
OCL et diagrammes UML
• Une expression OCL est définie dans le contexte d’une classe
– un type, une interface, une classe, etc.
– Elle s’applique sur un objet, instance de cette classe
• Étant donné un accès à un objet (p.ex. self), une expression OCL peut :
• accéder à la valeur des attributs :
– self .nbPages ou unLivre.nbPages
• appeler toute requête définie sur l’objet :
– self .getNbPages() ou unLivre.getNbPages()
• Rappel : Une requête (notée {isQuery} en UML) est une opération :
– qui a un type de retour (calcule une expression) ;
– et n’a pas d’effet de bord (ne modifie pas l’état du système).
• Attention : une opération avec effet de bord est proscrite en OCL ! Cest à dire ne
change pas la valeur de l’attribut)
11
OCL et diagrammes UML
• les éléments à l’extrémité d’une association sont accessibles par une
collection: unLivre.auteur : la collection des auteurs de unLivre
• multiplicité 1 : nécessairement un objet à l’extrémité (invariant
implicite): unLivre.éditeur
• multiplicité 0..1 (optionnel) :
– utiliser l’opération oclIsUndefined()
– unLivre.résumé. oclIsUndefined() est :
• vraie si pas de résumé,
• faux sinon
– Exemple d’utilisation : if unLivre.résumé.oclIsUndefined() then true else
unLivre.résumé.taille >= 60 endif 12
Contexte d’une expression OCL
13
Contexte d’une expression OCL
Exemple 1:
14
Contexte d’une expression OCL
Exemple 2:
15
Contexte d’une expression OCL
Exemple 2:
Version visuelle: la figure suivante présente une version alternative,
graphique de la contrainte sur l’âge la personne
Nommage de la contrainte:
16
Syntaxe d’OCL
17
Les types OCL de base
• Les types de base: boolean, Integer, real et String
• Les types UML: les classes UML sont considérés comme des types par OCL
les objets instances de ces classes sont donc considérés comme les valeurs
de ces types. Concernant l’opérateur if ... then ... else ...
Priorité des opérateurs
endif :
• la clause else est nécessaire et,
• les expressions du then et du else doivent
être de même type.
Les parenthèses peuvent être utilisées pour
changer la priorité.
18
Les types OCL de base et valeurs
• Tous les éléments du modèle sont des types (OclModelElementType),
– y compris les énumérations : Gender :: male,
• Type Tuple : enregistrement (produit cartésien de plusieurs types)
– Tuple {a : Collection(Integer) = Set{1, 3, 4}, b : String = ’foo’}
• OclMessageType :
– utilisé pour accéder aux messages d’une opération ou d’un signal,
– offre un rapport sur la possibilité d’envoyer/recevoir une opération/un signal.
• VoidType :
– a seulement une instance oclUndefined,
– est conforme à tous les types.
• Les collections: sont des types OCL dérivant des ensembles d’éléments et
fournissant plusieurs fonctions permettant la manipulation des collections.
• Les variables: il est possible de définir des variables à l’aide du mot clé : let.
Les variables OCL ont une valeur fixe. Elles sont des raccourcis qui peuvent
être utilisées dans d’autres expressions OCL.
• Les opérations ajoutées: la définition d’une nouvelle opération se fait à
travers le mot clé def. L’opération ajoutée ne peut être que des opérations de
sélection et doit être entièrement spécifiée en OCL.
19
Les types OCL de base et valeurs
Type Définition Exemple
Bag ensemble d’éléments avec Bag{7,54,22,98,9,54,20,21,22,23,24,25}
doublons possibles et sans ordre : Bag(Integer)
Sequence ensemble d’éléments avec Sequence{7,9,20,21,22,22,23,24,25,54,
doublons possibles et avec ordre 54,98} : Sequence(Integer)
Set ensemble d’éléments sans doublon Set{7,54,22,98,9,20,21,23,24,25} :
et sans ordre Set(Integer)
OrderedSet ensemble d’éléments sans OrderedSet{7,9,20,21,22,23,24,25,54,9
doublons et avec ordre 8} : OrderedSet(Integer)
UML OCL
Bag
isUnique Set
isUnique, OrderedSet
isOrdered
20
isOrdered Sequence
Opérations de la bibliothèque standard
sur les collections
Opération Description
size(): Integer nombre d’éléments dans la collection self
includes(object: T): Boolean est−ce que object est dans self- ?
excludes(object: T): Boolean est−ce que object n’est pas dans self ?
count(object: T): Integer nombre d’occurrences de object dans self
includesAll(c2: Collection(T)): est−ce que self contient tous les éléments de c2 ?
Boolean
excludesAll(c2: Collection(T)): est−ce que self ne contient aucun des éléments de c2 ?
Boolean
isEmpty(): Boolean est−ce que self est vide ?
notEmpty(): Boolean est−ce que self est non vide ?
sum(): T la somme (+) des éléments de self −− l’opérateur + doit
être défini sur le type des éléments de self
product(c2: Collection(T2)): Set( le produit (*) des éléments de self
Tuple(premier: T, second: T2)) 21
Une documentation d’OCL se trouve sur https://www.omg.org/spec/OCL/
Opérations de la bibliothèque standard
pour tous les objets
Opération Description
oclIsTypeOf(t : OclType) : Boolean Le résultat est vrai si le type de self et t sont identiques
oclIsKindOf(t : OclType) : Boolean vrai si t est le type de self ou un super-type de de self
oclIsNew() : Boolean Uniquement dans les post-conditions vrai si le
récepteur a été créé au cours de l’exécution de
l’opération.
oclAsType(t : OclType) : T Retourne le même objet mais du type t Nécessite que
oclIsKindOf(t) = true
allInstances() prédéfinie pour les classes, les interfaces et les
énumérations, I le résultat est la collection de toutes
les instances du type au moment de l’évaluation.
22
Autres Opérations
Opération Description
select (resp reject) Permet de spécifier le sous-ensemble de tous les éléments de
collection pour lesquels l’expression est vraie (resp. fausse pour
reject).
exists Retourne vrai si l’expression est vraie pour au moins un élément de la
collection.
forAll Retourne vrai si l’expression est vraie pour tous les éléments de la
collection.
collect Retourne la collection des valeurs (Bag) résultant de l’évaluation de
l’expression appliquée à tous les éléments de collection.
iterate Forme générale d’une itération sur une collection et permet de
redéfinir les précédents opérateurs.
collection−> iterate(elem : Type; answer : Type = | )
collection →operation(elem : T|expr)
collection →operation(elem|expr)
collection →operation(expr) 23
Opération peut être select, exists, forAll, collect
Autres Opérations
Select Exists
24
Autres Opérations
forAll collect
25
Autres Opérations
Iterate
• Remarque : Les opérateurs forAll, exist et
iterate acceptent plusieurs itérateurs. Dans ce
cas, il faut nommer tous les itérateurs !
26
Comment avoir de bonnes contraintes OCL?
• OCL ne remplace pas les explications en langage naturel.
– Les deux sont complémentaires !
– Comprendre (informel)
– Lever les ambiguïtés (OCL)
• Éviter les expressions OCL trop compliquées
– éviter les navigations complexes (utiliser let ou def)
– bien choisir le contexte (associer l’invariant au bon type !)
– éviter d’utiliser allInstances() :
• rend souvent les invariants plus complexes
• souvent difficile d’obtenir toutes les instances dans un système (sauf
BD !)
– décomposer une conjonction de contraintes en plusieurs (inv,
post, pre)
– Toujours nommer les extrémités des associations (rôle des
objets)
27
Exercice 1
• Soit le diagramme de classes suivant:
• Exprimer les contraintes OCL:
– Le nom d’un professeur ne peut être nul
– Le sigle d’un cours fait toujours 3 caractères
– Le coefficient d’un cours est entre 0.0 et 100.0
– Un professeur doit travailler dans l’université qui dispense
le cours pour l’enseigner
28
Exercice 1
Le nom d’un professeur ne peut être nul
Le sigle d’un cours fait toujours 3 caractères
Le coefficient d’un cours est entre 0.0 et 100.0
Un professeur doit travailler dans l’université
qui dispense le cours pour l’enseigner
29
Exercice 2
• Donnez un exemple de pré-condition et post-condition pour
MyInteger::diviserPar()
30
Exercice 3
• Soit le diagramme suivant, donner en OCL les contraintes
mentionnées sur le diagramme.
31
Exercice 3
32
Exercice 4
• Soit le diagramme suivant
Donnez une contrainte OCL qui spécifie :
1. A un objet compte correspond un et
un seul objet Personne.
2. La méthode débiter(somme :int), où le
paramètre somme doit être positif
et nouveau_solde = ancien_solde -
somme.
3. Il n'existe pas de clients de la banque
dont l'âge est inférieur à 18 ans.
4. L'ensemble des clients de la banque
associé à un compte contient le
propriétaire de ce compte. 33
Exercice 4
• Soit le diagramme suivant
34