Chapitre 4: Object Constraint Language (OCL)

Page 1 sur 39Lecteur de document UniversityLib

Chapitre 4: Object Constraint Language (OCL)

Programming, Object-Oriented Modeling, UML · course

Voir tous les documents en génie logiciel

Chapitre4: Object Constraint Language (OCL)

Cours Ingénierie Dirigée par les modèles Cours Ingénierie Dirigée par les modèles

Niveau: II3 ILSI Enseignante: Rim DRIRA [email protected] Bureau 215

AU: 2016/2017

Plan

1. Pourquoi OCL

2. Contexte d’une contrainte

3. Syntaxe d’OCL

2

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

OCL (Object Constraint Language)

 UML permet d’exprimer différents types de contraintes:

 contraintes structurelles: les attributs, les différents types de relations

entre classes, cardinalités, etc.

 contraintes de type: le typage des attributs, etc.  contraintes prédéfinies sur les associations: {subset}, {xor}, etc.  contraintes en langue naturelle (commentaires)  contraintes en langue naturelle (commentaires)  diverses autres contraintes comme les contraintes de visibilité, des

classes abstraites, etc.

 TOUTEFOIS

 Certaines contraintes ne peuvent pas être formalisées avec UML.

 Afin de combler cette lacune, l’OMG a proposé un langage d’expression

de contraintes appelé OCL.

3

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Pourquoi OCL ? Illustration par l'exemple

 Application bancaire qui manipulent les classes Compte,

Personne et Banque

1.

2.

3.

4.

5.

6.

7.

8.

Un client peut posséder plusieurs comptes

Un compte doit avoir un solde toujours positif.

Un client peut être client de plusieurs banques

Un client d'une banque possède au moins un compte dans cette banque banque

Les clients de la banque associée à un compte doivent contenir le propriétaire de ce compte

Une banque gère plusieurs comptes

Une banque possède plusieurs clients

Les méthodes qu’on pourra appliquer sur Compte sont: créditer(int), débiter(int) et int getSolde()

 Quelles sont les spécifications non exprimées par le

diagramme de classe proposé??

4

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Pourquoi OCL ? Illustration par l'exemple

 Le diagramme de classe ne permet pas d’exprimer:

2. Un compte doit avoir un solde toujours positif

4. Un client d'une banque possède au moins un compte dans cette

banque

5. Les clients de la banque associée à un compte doivent 5. Les clients de la banque associée à un compte doivent

contenir le propriétaire de ce compte

5

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Pourquoi OCL ? Illustration par l'exemple

 Diagramme d'objets cohérent avec le diagramme de classes et la

spécification:

6

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Pourquoi OCL ? Illustration par l'exemple

 Diagramme d'objets cohérent avec le diagramme de classes mais

qui ne respecte pas la spécification attendue.

 Une personne a un compte dans une banque où elle n'est pas cliente

 Une personne est cliente d'une banque mais sans y avoir de compte

7

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Diagrammes UML insuffisants

 Pour spécifier complètement une application

 Diagrammes UML seuls sont généralement insuffisants

 Nécessité de rajouter des contraintes

 Comment exprimer ces contraintes ?

 Langue naturelle mais manque de précision, compréhension pouvant

être ambigüe

 Langage formel avec sémantique précise : OCL

8

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

OCL, c’est quoi?

 Langage de description de contraintes d'UML, peut s’appliquer sur

différents diagrammes UML

 Standardisé par l'OMG

 Version 2.3.1: http://www.omg.org/spec/OCL/ISO/19507/PDF/

 Version actuelle: 2.5 http://www.omg.org/spec/OCL/2.5

 Objectif: Spécifier des contraintes supplémentaires importantes qui n'ont pas pu être spécifiés avec les éléments de modélisation d'UML

 S'applique aussi sur MOF

9

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Utilisation d’OCL

 OCL permet principalement d'exprimer deux types de contraintes sur l'état

d'un objet ou d'un ensemble d'objets:

 Invariant de classe: une contrainte qui doit être respectée en permanence

par toutes les instances d'une classe.

 pré-condition et post-conditions à l'exécution d'une opération:

 Permet aussi d’exprimer:  Permet aussi d’exprimer:

 contraintes sur la valeur retournée par une méthode

 règles de dérivation des attributs

 Gardes sur transitions de diagrammes d'états ou de messages de diagrammes

de séquence/communication

 Etc.

10

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Contexte d’une contrainte OCL

 Une contrainte OCL est toujours associée à un élément d’un

modèle, il est appelé le contexte de la contrainte.

 Exemple :

Publicité

 context Compte : l'expression OCL s'applique à la classe Compte, c'est-à-dire

à toutes les instances de cette classe à toutes les instances de cette classe

 . permet d'accéder à une caractéristique d'un objet (méthode,

attribut, terminaison d'association)

 Exemple : banque.clients donne l’ensemble d’objets de type client

associé à une banque

11

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Retour à l’Exemple

 Exprimer le fait que le solde d’un compte doit être positif ne peut pas être fait avec UML mais peut être formalisé avec la contrainte OCL suivante :

Context Compte

Inv: solde>0

 Exprimer le fait que les clients de la banque associée à un compte doivent contenir le propriétaire du compte avec OCL:

Context Compte

Inv: banque.clients -> includes (propriétaire)

12

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Pré et post conditions

 Pour spécifier une opération

 Précondition : état qui doit être respecté avant l'appel de l'opération

 Postcondition : état qui doit être respecté après l'appel de l'opération

 Mots-clés : pre et post

 Dans la postcondition, deux éléments particuliers sont utilisables  Dans la postcondition, deux éléments particuliers sont utilisables  Attribut result : référence la valeur retournée par l'opération

 mon_attribut@ pre : référence la valeur de mon_attribut avant l'appel de

l'opération

 Syntaxe pour préciser l'opération

 context ma_classe::mon_op(liste_param) : type_retour

13

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Pré et post conditions

Exemple1

context Compte::débiter(somme : Integer)

pre: somme > 0

post: solde = solde@pre – somme

 La somme à débiter doit être positive pour que l'appel de l'opération soit valide

 Après l'exécution de l'opération, l'attribut solde doit avoir pour valeur la différence de sa valeur  Après l'exécution de l'opération, l'attribut solde doit avoir pour valeur la différence de sa valeur

avant l'appel et de la somme passée en paramètre avant l'appel et de la somme passée en paramètre

Exemple2

context Compte::getSolde() : Integer

post: result = solde

 Le résulat retourné doit être le solde courant

 Attention! On ne décrit pas comment l'opération est réalisée mais des contraintes sur l'état

avant et après son exécution

14

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Conception par contrat pour opérations

 Pre et postconditions permettent de faire une conception par

contrat

 Contrat passé entre l'appelant d'une opération et l'appelé (celui qui

exécute l'opération)

 Si l'appelant respecte les contraintes de la précondition alors l'appelé  Si l'appelant respecte les contraintes de la précondition alors l'appelé

s'engage à respecter la post-condition

 Si l'appelant ne respecte pas la précondition, alors le résultat de

l'appel est indéfini

 Pour exemple précédent: Si l'appelant de l'opération débiter passe une somme positive en paramètre, alors le compte est bien débité de cette somme

15

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Invariant

 Un invariant exprime une contrainte sur un objet ou un groupe

d'objets qui doit être respectée en permanence

 Mot-clé : inv

 Exemple: context Compte inv: solde > 0

 Pour toutes les instances de la classe Compte, l'attribut solde doit

toujours être positif

16

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Accès aux objets, navigation

 Dans une contrainte OCL associée à un objet, on peut

 Accéder à l'état interne de cet objet (ses attributs)  Naviguer dans le diagramme : accéder de manière transitive à tous les objets

(et leur état) avec qui il est en relation

 Nommage des éléments

 Pour les attributs ou paramètres d'une opération, on utilise le nom  Pour les attributs ou paramètres d'une opération, on utilise le nom

directement

 Pour le(s) objet(s) en association, on utilise le nom du rôle d'association du côté de cette classe (dans les exemples, s’il n’y a pas de noms de rôles, je vais utiliser le nom en minuscule de la classe (comme OCL 2.2))  Si cardinalité de 1 ou 0..1 pour une association : référence un objet  Si cardinalité > 1 : référence une collection d'objets

17

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Accès aux objets, navigation

Exemples, dans le contexte de la classe Compte

 solde : attribut référencé directement  banque : objet de la classe Banque (référence via le nom de la classe) associé

au compte

 propriétaire : objet de la classe Personne (référence via le nom de rôle

d'association) associée au compte d'association) associée au compte

 banque.clients : ensemble des clients de la banque associée au compte

(référence par transitivité)

 banque.clients.age : ensemble des âges de tous les clients de la banque

associée au compte

 Le propriétaire d'un compte doit avoir plus de 18 ans context Compte inv: propriétaire.age >= 18

18

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Navigation vers une classe association

 Dans contexte Entreprise

 Self.Contrat

 Dans contexte Personne

 Self.Contrat

 Comment naviguer vers l’objet Encadrement de son responsable ?

o

self.Encadrement [responsable]

 Comment naviguer vers l’objet Encadrement de son agentSecrétariat ?

o

self.Encadrement [agentSecrétariat]

19

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Opérations sur objets et collections  OCL propose un ensemble de primitives utilisables sur les collections

 size() : retourne le nombre d'éléments de la collection  isEmpty() : retourne vrai si la collection est vide  notEmpty() : retourne vrai si la collection n'est pas vide  includes(obj) : vrai si la collection inclut l'objet obj  excludes(obj) : vrai si la collection n'inclut pas l'objet obj  including(obj) : la collection référencée doit être cette collection en incluant l'objet  including(obj) : la collection référencée doit être cette collection en incluant l'objet

Publicité

obj

 excluding(obj) : idem mais en excluant l'objet obj  includesAll(ens) : la collection contient tous les éléments de la collection ens  excludesAll(ens) : la collection ne contient aucun des éléments de la collection ens  Sum(): addition de tous les éléments de la collection  count(obj) : retourne le nombre d'occurences d'un objet dans la collection

 Syntaxe d'utilisation : objetOuCollection -> primitive

 self: pseudo-attribut référençant l'objet courant

20

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Opérations sur objets et collections

Exemples, invariants dans le contexte de la classe Compte

 propriétaire -> notEmpty() : il y a au moins un objet Personne

associé à un compte

 propriétaire -> size() = 1 : le nombre d'objets Personne associés à

un compte est de 1 un compte est de 1

 banque.clients -> size() >= 1 : une banque a au moins un client

 banque.clients -> includes(propriétaire) : l'ensemble des clients de la banque associée au compte contient le propriétaire du compte

 banque.clients.compte -> includes(self) : le compte appartient à

un des clients de sa banque

21

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Opérations sur objets et collections

Autre exemple

context Banque :: creerCompte(p : Personne) : Compte

post: result.oclIsNew() and compte = compte@pre -> including(result) and p.compte = p.compte@pre -> including(result) and result.proprietaire = p and result.banque = self

 Un nouveau compte est créé. La banque doit gérer ce nouveau compte.  Un nouveau compte est créé. La banque doit gérer ce nouveau compte.

 Le client passé en paramètre doit posséder ce compte. Le nouveau compte

est retourné par l'opération.

 OclIsNew()

 Primitive indiquant qu'un objet doit être créé pendant l'appel de l'opération

(à utiliser dans une postcondition)

22

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Relations ensemblistes entre collections

 union: retourne l'union de deux collections

 intersection: retourne l'intersection de deux collections

 Exemples

 (col1 -> intersection(col2)) -> isEmpty() renvoie vrai si les collections  (col1 -> intersection(col2)) -> isEmpty() renvoie vrai si les collections

col1 et col2 n'ont pas d'élément en commun

 col1 = col2 -> union(col3) La collection col1 doit être l'union des éléments

de col2 et de col3

23

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Opérations sur les éléments d'une collection

 OCL permet de vérifier des contraintes sur chaque élément d'une collection ou de définir une sous-collection à partir d'une collection en fonction de certaines contraintes

 Primitives offrant ces services et s'appliquant sur une collection col

 select : retourne le sous-ensemble de la collection col dont les éléments respectent

la contrainte spécifiée  reject : idem mais ne garde que les éléments ne respectant pas la contrainte reject : idem mais ne garde que les éléments ne respectant pas la contrainte  collect : retourne une collection (de taille identique) construite à partir des

éléments de col. Le type des éléments contenus dans la nouvelle collection peut être différent de celui des éléments de col.

 exists : retourne vrai si au moins un élément de col respecte la contrainte spécifiée

et faux sinon

 forAll : retourne vrai si tous les éléments de col respectent la contrainte spécifiée

(pouvant impliquer à la fois plusieurs éléments de la collection)

24

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Opérations sur les éléments d'une collection

Syntaxe de ces opérations : 3 usages

 collection -> primitive( expression )

 La primitive s'applique aux éléments de la collection et pour chacun d'entre eux, l'expression expression est vérifiée. On accède aux attributs/relations d'un élément directement.

 collection -> primitive( elt : type | expression)

 On fait explicitement apparaître le type des éléments de la collection (ici

type). On accède aux attributs/relations de l'élément courant en utilisant elt (c'est la référence sur l'élément courant)

 collection -> primitive(elt | expression)

 On nomme l'attribut courant (elt) mais sans préciser son type

25

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Opérations sur les éléments d'une collection

Exemples dans le contexte de la classe Banque:

 compte -> select( c | c.solde > 1000) Retourne une collection

contenant tous les comptes bancaires dont le solde est supérieur à 1000 €  compte -> reject( solde > 1000) Retourne une collection contenant tous les comptes bancaires dont le solde n'est pas supérieur à 1000 €  compte -> collect( c : Compte | c.solde) Retourne une collection  compte -> collect( c : Compte | c.solde) Retourne une collection

contenant l'ensemble des soldes de tous les comptes

 (compte -> select( solde > 1000 )) -> collect( c | c.solde)

Retourne une collection contenant tous les soldes des comptes dont le solde est supérieur à 1000 €

 inv: not( clients -> exists (age < 18) )

 Il n'existe pas de clients de la banque dont l'age est inférieur à 18 ans  not Prend la négation d'une expression

26

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Opérations sur les éléments d'une collection

Autre Exemple:

 context Personne inv: Personne.allInstances() ->

forAll(p1, p2 | p1 <> p2 implies p1.nom <> p2.nom)

 Il n'existe pas deux instances de la classe Personne pour lesquelles

l'attribut nom a la même valeur : deux personnes différentes ont un l'attribut nom a la même valeur : deux personnes différentes ont un nom différent

 AllInstances()

 Primitive s'appliquant sur une classe (et non pas un objet) et

retournant toutes les instances de la classe référencée (ici la classe Personne)

27

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Types OCL : types de base

 Exemples

context Personne inv: if age < 18 -- vérifie age de la personne then compte -> isEmpty() -- pas majeur : pas de compte else compte -> notEmpty() -- majeur : doit avoir au moins un compte Endif context Personne inv: compte -> notEmpty() implies banque -> notEmpty() -- Si une personne possède au moins un compte bancaire, alors elle est cliente d'au

moins une banque

28

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Enumération

 Utilisation d'une valeur d'une énumération

 NomEnum::valeur

 Exemples:

context Homme context Homme

inv: sexe = Gender::male

context Femme

inv: sexe = Gender::female

29

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Propriétés prédéfinies en OCL

Pour objets

Publicité

 oclIsTypeOf(type) : l'objet est du type type

 oclIsKindOf(type) : l'objet est du type type ou un de ses sous-types

 oclInState(état) : l'objet est dans l'état état  oclInState(état) : l'objet est dans l'état état

 oclIsNew() : l'objet est créé pendant l'opération

 oclAsType(type) : l'objet est « casté » en type type

 oclIsUndefined() : la propriété (association par exemple) n'a pas

été initialisée (équivalent d'un « null »)

30

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Règles de précédence

 Ordre de précédence pour les opérateurs/primitives du plus au moins prioritaire

 @pre

 . et ->

 not et -

 * et /

 + et -  + et -

 if then else endif

 >, <, <= et >=

 = et <>

 and, or et xor

 implies

 Parenthèses permettent de changer cet ordre

31

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Variables

 Pour faciliter l'utilisation de certains attributs ou calculs de valeurs on peut

définir des variables

 Dans une contrainte OCL : let ... in ...

context Personne

inv: let argent = compte.solde -> sum() in age >= 18 implies argent > 0

 Une personne majeure doit avoir de l'argent

 Pour l'utiliser partout : def

context Personne

def: argent : Integer = compte.solde -> sum()

context Personne

inv: age >= 18 implies argent > 0

32

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

OCL: Bilan

 Permet d’exprimer des contraintes supplémentaires qu’il n’est pas

possible d’exprimer avec UML

 Langage formel mais simple à utiliser, non ambigu, grammaire précise

 Langage déclaratif : les contraintes ne sont pas opérationnelles.

 Une expression OCL décrit une contrainte à respecter et non pas un code à  Une expression OCL décrit une contrainte à respecter et non pas un code à

exécuter

 Langage sans effet de bord : les instances ne sont pas modifiées par

les contraintes.

 Peut être utilisé au niveau M3 (sur Ecore, MOF, UML), M2(sur UML et sur les méta-modèles MOF et Ecore), M1 (diagrammes UML classe, état, etc.)

33

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Exercices Exercices

34

Exercice1

 Ajoutez un attribut mère de type Personne

dans la classe Personne.

 Ecrivez une contrainte précisant que la mère d'une personne ne peut être cette personne elle-même et que l'âge de la mère doit être elle-même et que l'âge de la mère doit être supérieur à celui de la personne

Solution:

context Personne inv:

self.mere <> self and self.mere.age > self.age

35

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Exercice2

 Indiquez qu’une personne mariée est forcément majeur

 Solution: context Personne inv: marié implies majeur

 Trouvez une version plus compacte de l’expression suivante

context Personne inv : if age >=18 then majeur=vrai else majeur=faux endif  Solution: context Personne inv: majeur = age >= 18

36

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Exercice3

 Les deux contraintes suivantes sont-elles équivalentes ?

 Contexte C1 inv: c2->forAll(c:C2| c.c3->notEmpty() implies c.attr2=c.c3.attr3)

 Contexte C2 inv: C2.allInstances()->forAll(c:C2| | c.c3->notEmpty() implies

c.attr2=c.c3.attr3)

Solution

 NON : la première dit que pour des instances de C2 et C3 liées avec une instance de C1, les attributs attr2 et attr3 sont égaux, mais n'impose rien à des instances de C2 et C3 non liées à une instance de C1 (et il y en a à cause de la multiplicité).

 La deuxième dit que pour tout couple d'instances de C2 et C3 liées, ces deux

attributs sont égaux.

37

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Exercice4

Exprimer en OCL les contraintes suivantes:

1.

2.

3.

4.

38

Dans une compagnie, un manager doit travailler et avoir plus de 40 ans. Le nombre d'employé d'une compagnie est non nul

Une personne considérée comme au chômage ne doit pas avoir de salaires et une personne qui travaille doit avoir au moins un revenu de 500 DT par mois.

Dans le contexte de la classe Job: l’âge de l’employé doit être supérieur à 21.

Tous les enfants d'une personne ont bien cette personne comme parent et inversement

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017

Exercice4

1. context Company

inv: self.manager.isUnemployed = false and self.manager.age > 40 and self.job -> notEmpty()

2. context Person

Inv: let money : Real = self.job.salary->sum() in if isUnemployed then money =0 else money >= 500 Endif Endif Ou bien context Person inv: if isUnemployed=true then self.job ->isEmpty() else self.job.salary->sum()

>= 500

3. context Job inv: self.employee.age > 21 4. context Person inv: children -> notEmpty() implies children -> forAll ( p :

Person |p.parents -> includes(self))

context Person inv: parents -> forAll ( p : Person |p.children -> includes (self))

39

R.DRIRA ENSI-II3 ILSI Chapitre4: OCL

2016-2017