# Object Constraint Language

L'Object Constraint Language (OCL) és un llenguatge que permet definir expressions formals vinculades a elements de models UML. Aquestes expressions són bàsicament restriccions, regles de derivació i condicions. OCL fou desenvolupat inicialment el 1995 per IBM i posteriorment es va integrar amb l'UML. OMG el va adoptar com a estàndard el 1997.

## Elements principals del llenguatge

A continuació s'introdueixen mitjançant exemples els elements principals de l'OCL. Els exemples es basaran en el model UML de la figura. És un model molt simplificat d'un sistema de gestió d'inscripcions a esdeveniments.

### Exemple 1: Invariant d'Esdeveniment

Un invariant és una restricció vinculada a una classe d'un model UML. La restricció ha de ser certa (o s'ha de satisfer) per cada instància de la classe.
En el model de la figura, un exemple d'invariant és:
context Esdeveniment inv:
self.nombreInscrits <= self.nombrePlacesOfertes
La primera línia indica que s'està definint un invariant (inv) vinculat (context) a la classe Esdeveniment. La restricció es defineix en la segona línia, i es tracta d'una condició que ha de ser certa per cada instància d'Esdeveniment.
El terme self denota una instància del context (Esdeveniment en aquest cas). L'expressió self.nombreInscrits, on nombreInscrits és un atribut d'Esdeveniment, denota el valor de l'atribut per a la instància self. Semblantment, l'expressió self.nombrePlacesOfertes denota el valor de l'atribut nombrePlacesOfertes per a la instància self. La restricció indica doncs que, per cada esdeveniment, el nombre d'inscrits a l'esdeveniment no pot ser superior al nombre de places ofertes.

### Exemple 2: Invariant d'Inscripcio

Una restricció molt freqüent és la que requereix que no hi hagi dues instàncies d'una classe que tinguin el mateix valor d'un dels seus atributs. En l'exemple de la figura això passa en la classe Inscripció, perquè no hi poden haver dues inscripcions que tinguin el mateix número. En OCL es pot expressar així:
context Inscripcio inv:
Inscripcio.allInstances->isUnique(numero)
L'expressió Inscripcio.allInstances denota el conjunt de totes les instàncies de la classe Inscripcio. L'OCL té diverses operacions que es poden aplicar a conjunts d'instàncies. L'aplicació es fa escrivint el símbol ->operació a continuació del conjunt, En l'exemple, hi ha ->isUnique(numero) per indicar que s'aplica l'operació isUnique(numero) al conjunt denotat per Inscripcio.allInstances.
L'operació isUnique(nom_atribut) dona el resultat de Cert (true) si no hi ha dues instàncies del conjunt al qual s'aplica que tinguin el mateix valor de l'atribut nom_atribut, i el resultat Fals (false) en cas contrari. En l'exemple, ->isUnique(numero) serà cert si no hi ha dues inscripcions que tinguin el mateix número.

### Exemple 3: Invariant de Persona

Un invariant que, en OCL, té una forma semblant a l'anterior és la restricció que una persona no pot estar inscrita més d'una vegada a un mateix esdeveniment. En OCL es pot expressar així:
context Persona inv:
self.inscripcio->isUnique(esdeveniment)
L'expressió self.inscripcio és un exemple de navegació, a través d'una associació, des d'una instància d'una classe cap a una altra classe. El resultat de la navegació és un conjunt d'instàncies de la classe d'arribada. En l'exemple, es navega des d'una instància (self) de Persona a través de l'associació que hi ha entre Persona i Inscripcio. El resultat és el conjunt de les inscripcions de self. Aquest conjunt pot ser buit si self no ha fet cap inscripció.
L'expressió isUnique(esdeveniment) és semblant a la de l'exemple anterior, però en comptes d'un atribut hi ha una navegació des d'una inscripció cap a la classe Esdeveniment. El resultat de la navegació és una sola instància d'Esdeveniment.
L'operació isUnique(esdeveniment) dona el resultat de Cert (true) si no hi ha dues inscripcions del conjunt self.inscripcio que siguin del mateix esdeveniment, i el resultat Fals (false) en cas contrari.

### Exemple 4: Regla de derivació de nombreInscrits

Una regla de derivació és una expressió que permet derivar uns elements a partir d'altres. OCL permet definir formalment aquestes expressions en UML.
En la figura, un exemple de derivació és l'atribut nombreInscrits de la classe Esdeveniment. El valor d'aquest atribut és el nombre d'inscrits a un cert esdeveniment. En OCL, es pot expressar així:
context Esdeveniment::nombreInscrits:Integer
derive: self.inscripcio->size
En aquest cas, el context indica la classe/atribut que es deriva. El valor de l'atribut per a una instància de la classe el dona l'expressió que segueix a derive.
En l'exemple, el valor és self.inscripcio->size. En aquesta expressió, self.inscripció és el conjunt d'instàncies d'Inscripció al qual s'arriba navegant per l'associació Inscripcio-Esdeveniment des d'una instància (self) d'esdeveniment. L'operació size, aplicada a un conjunt, dona el nombre d'instàncies d'aquest conjunt. El nombre pot ser zero.

### Exemple 5: Precondició de l'operació novaInscripció

En UML, una precondició d'una operació és una condició que ha de ser certa abans d'executar l'operació. Les precondicions es poden expressar formalment en OCL.
En l'exemple de la figura, hi ha l'operació novaInscripció de la classe Esdeveniment, que s'executa cada vegada que es vol afegir una inscripció a l'esdeveniment corresponent. Una precondició d'aquesta operació és que l'esdeveniment no estigui ja ple. En OCL, es podria expressar així:
context Esdeveniment::novaInscripcio(nomPersona:String)
pre: self.nombreInscrits < self.nombrePlacesOfertes
En aquest cas, el context indica la classe/operació per a la qual es defineix una precondició. La precondició l'expressa a continuació de la paraula clau pre.
En l'exemple, la condició és self.nombreInscrits < self.nombrePlacesOfertes, és a dir, que el nombre d'inscrits que hi ha quan es va a executar l'operació sigui menor que el nombre de places ofertes en aquell moment.

### Exemple 6: Postcondició de l'operació novaInscripcio

En UML, una postcondició d'una operació és una condició que ha de ser certa un cop executada l'operació. Les postcondicions es poden expressar formalment en OCL.
En l'exemple de la figura, una postcondició de l'operació novaInscripció és que la persona està inscrita a l'esdeveniment. En OCL es podria expressar així:
context Esdeveniment::novaInscripcio(nomPersona:String)
post: Inscripcio.allInstances->one(esdeveniment = self and inscrit.nom = nomPersona)
Com en l'exemple anterior, el context indica la classe/operació per a la qual es defineix una postcondició. La postcondició s'expressa a continuació de la paraula clau post.
La postcondició usa l'operació OCL one(condició) que s'aplica a un conjunt. El resultat és Cert si hi ha un sol element en el conjunt per al qual la condició és Cert; en cas contrari el resultat és Fals.
En l'exemple, el conjunt és el conjunt de totes les inscripcions (Inscripcio.allInstances). S'exigeix que n'hi hagi exactament una tal que el seu esdeveniment sigui aquell en el qual s'invoca l'operació (self) i que la persona inscrita tingui el nom indicat en el paràmetre de l'operació (nomPersona).

## Referències

* ↑ OMG «Object Constraint Language. Version 2.4». OMG Document Number: formal/2014-02-03, 01-02-2014.
* ↑ Cabot, Jordi; Gogolla, Martin «Object Constraint Language (OCL):A Definitive Guide». Lecture Notes in Computer Science, vol 7320. Springer, Berlin, Heidelberg, 2012.
* 1 2 OMG «OMG Unified Modeling Language Version 2.5.1». OMG Document Number: formal/2017-12-05, 01-12-2017.

## Enllaços externs

* USE: UML-based Specification Environment
* Eclipse OCL (Object Constraint Language)