61
OCL – The Object Constraint Language in UML Natalia Mordvaniuk, Javier Gené Martín

OCL – The Object Constraint Language in UMLima.udg.edu/~sellares/EINF-ES2/Present1213/PresentacioOCL.pdf · Classes i subclasses Conclusions. 4 OCL és un llenguatge formal textual

  • Upload
    haduong

  • View
    227

  • Download
    0

Embed Size (px)

Citation preview

OCL – The Object Constraint Language in

UML

Natalia Mordvaniuk,Javier Gené Martín

Index

Introducció

Història

Companyies al darrera de OCL

On es fa servir el OCL?

Restriccions, constexts i self

Exemple: Un sistema hipotecari

Especificació OCL de les restriccions

Exemple: programes de fidelització

Invariants amb navegació a traves d'extrems d'associació

Invariants que usen navegació desde les classes d'associació

Invariants que usen la navegació a través d'associacions amb multiplicitat múltiple

Index

Navegació en les col·leccions

Els tipus de col·leccions

Operacions de les col·leccions

Característiques de les classes

Propietats predefinides en tots els objectes

Canviant de context

Exemple dels estudiants i les matricules

Navegació de les classes a través de les associacions cícliques

Navegació a través de l'Associació qualificada

Classes i subclasses

Conclusions

4

OCL és un llenguatge formal textual per definir restriccions sobre objectes. (Object Constraint Language)

Llenguatge notacional

Subconjunt de l'UML

Estàndard

S'utilitza en:

model conceptual

model d'operacions

model d'objectius

disseny

navegació de models estructurals.

Introducció

5

Introducció

Per què és necessari un llenguatge formal?

Aconseguir una especificació precisa

Descriure característiques addicionals

Escriure característiques no ambigües

6

Introducció

Per què OCL i no altres llenguatges formals?

No cal una bona formació matemàtica

És un llenguatge formal, fàcil de llegir i escriure

És un llenguatge complet en sí mateix

És un llenguatge tipat, de manera que cada expressió d'OCL té un tipus

7

Introducció

Millor documentació → Constraints afegeixen informació sobre els elements del model i la seva relació amb els models utilitzats en UML. És una forma de documentar un model.

Més precisió → les restriccions OCL tenen una semàntica formal, i, per tant, es poden utilitzar per reduir l'ambigüitat en els models UML.

Comunicació sense malentesos → els models d'UML s'utilitzen per a la comunicació entre els desenvolupadors. L'ús de les restriccions OCL, els modeladors es poden comunicar sense les ambigüitats.

8

D'expressions

De models

Formal

Introducció

OCL recull les característiques d'un llenguatge:

9

Desenvolupat per primera vegada el 1995 amb el nom Ibel per la IBM (International Business Machine) per al modelatge de negoci

IBM el va proposar a OMG per l'anàlisi orientat a objectes i disseny estàndard. Després OCL es va fusionar amb UML 1.1.

OCL va ser utilitzat per definir el UML 1.2.

Història

10

Companyies al darrere de OCL

Microsoft IBM Hewlett-Packard Oracle Sterling Software MCI Systemhouse Entre altres com: Unisys, ICON Computing,

IntelliCorp, i-Logix, ObjecTime, Platinum Technology, Ptech, Taskon, Reich Technologies, Softeam.

11

On es fa servir el OCL?

Per especificar invariants per les clases i tipus Per especificar les pre- i post- condicions dels

diferents mètodes. Com un llenguatge de navegació. Per especificar les restriccions sobre les

operacions. Per testejar els requisits i les especificacions.

12

Restriccions (invariants), contexts i Selfs

A constraint (invariant) és una expressió booleana OCL que és evaluada a cert o a fals.

Cada restricció s'enllaça a un tipus específic (classe, associació de classe, interfície) dintre del model UML

Els objectes de context poden ser denotats amb la paraula clau ‘self’.

El context pot ser especificat com a:

Context <context name> invariant <nom_invariant>? :

<restricció>

13

Exemple: Un sistema hipotecari

La hipoteca d'una casa pertany al propietari de la casa, el qual és el prestatari de la hipoteca.

La data d'inici d'una hipoteca ha de ser abans de la seva data de finalització.

14

Especificació OCL de les restriccions:

1. context Mortgage context Mortgage invariant: self.security.owner = self.borrower invariant: security.owner =

borrower

2. context Mortgage context Mortgage invariant: self.startDate < self.endDate invariant: startDate <

endDate

15

Altres exemples sobre les restriccions

Tots els jugadors han de ser majors d'edat:

El nombre de persones en cada habitació no és superior al nombre de llits en aquesta habitació.

context Player invariant:self.age >=18

context Room invariant:guests -> size <= numberOfBeds

Room room guests Guest

numberOfBeds: Integer*

Playerage: Integer

16

Exemple: programes de fidelització

Problema: - Una empresa s'encarrega dels programes de fidelitat (class

LoyaltyProgram) per les empreses (class ProgramPartner) que ofereixen als seus clients diversos tipus de bons.

- Els extres es donen en forma de punts de bonificació.

- Les empreses ofereixen serveis (class Service).

- Cada client pot entrar al programa de fidelitat mitjançant l'obtenció d'un carnet de soci (class CustomerCard).

- Els objectes de class Customer representen a les persones.

17

Exemple: programes de fidelització - Una CustomerCard o (targeta membre) pertany a una persona, però

es pot fer servir per a tota una família o empresa.

- Els programes de fidelitat permeten als clients estalviar punts de bonificació, amb els quals el client es pot "comprar" serveis del programa dels socis.

- Un compte de fidelitat(LoyaltyAccount) s'emet quan un client pertany

a un programa de fidelitat (class Membership).

- Les transaccions (class Transaction) en els comptes de fidelitat impliquen que hi hagin diferents serveis prestats pels socis del programa de fidelitat i es realitzen amb una única targeta. Hi ha dos tipus de transaccions: Earning (sumen punts) i burning (resten punts).

- La durada dels membres determina diferents nivells dels serveis (class serviceLevel).

18

LoyaltyProgram

enroll(c:Customer)

Service

condition: BooleanpointsEarned: IntegerpointsBurned: Integerdescription: String

0..*deliveredServices

Membership

LoyaltyAccount

points: Integer

earn(i: Integer)burn(i: Integer)isEmpty(): Boolean

Customer

name: Stringtitle:StringisMale: BooleandateOfBirth: Date

CustomerCard

valid: BooleanvalidFrom: DategoodThru: Datecolor: enum{silver, gold}printedName: String

0..*0..*

age(): Integer

programs

owner

card0..*card

ProgramPartner(Empresa)

numberOfCustomers: Integer

partners

1..*

1..*

ServiceLevel

name: String

availableServices

0..*

{ordered} 1..*0..1

0..*

actualLevel

Transaction

points: Integerdate:Date

program(): LoyaltyProgram

0..*transactions

card

transactions0..*transactions

0..*

Burning Earning

Date

$now: Date

isBefore(t:Date): BooleanisAfter(t:Date): Boolean=(t:Date): Boolean

1

1

1

1

1

1

1

1

1

level

generatedBy

partner 1

account

19

Using OCL in Class Diagrams

LoyaltyAccount

points: Integer

earn(i: Integer)

burn(i: Integer)

isEmpty(): Boolean

{ points >= 0 }

<<postcondition>>points = points@pre - i

class invariant

postcondition for burn operation<<postcondition>>result = (points=0)

<<precondition>>points >= i and i >= 0

precondition for burn operation

<<postcondition>>points = points@pre + i

<<precondition>>i >= 0

20

Invariants en els atributs

Invariants en els atributs:

context Customerinvariant agerestriction: age >= 18

context CustomerCardinvariant correctDates: validFrom.isBefore(goodThru)

El tipus de validFrom i goodThru és Data.isBefore(Date):Boolean és una operació amb Data.

La classe on s'ha de posar la invariant és el context d'aquesta invariant.

21

LoyaltyProgram

enroll(c:Customer)

Service

condition: BooleanpointsEarned: IntegerpointsBurned: Integerdescription: String

0..*deliveredServices

Membership

LoyaltyAccount

points: Integer

earn(i: Integer)burn(i: Integer)isEmpty(): Boolean

Customer

name: Stringtitle:StringisMale: BooleandateOfBirth: Date

CustomerCard

valid: BooleanvalidFrom: DategoodThru: Datecolor: enum{silver, gold}printedName: String

0..*0..*

age(): Integer

programs

owner

cards0..*card

ProgramPartner(Empresa)

numberOfCustomers: Integer

partners

1..*

1..*

ServiceLevel

name: String

availableServices

0..*

{ordered} 1..*0..1

0..*

actualLevel

Transaction

points: Integerdate:Date

program(): LoyaltyProgram

0..*transactions

card

transactions0..*transactions

0..*

Burning Earning

Date

$now: Date

isBefore(t:Date): BooleanisAfter(t:Date): Boolean=(t:Date): Boolean

1

1

1

1

1

1

1

1

1

level

generatedBy

partner 1

account

22

Invariants amb navegació a traves d'extrems d'associació – Roles (1)

- Navegació sobre les associacions s'usa per referir-se als objectes associats, a partir de l'objecte de context:

context CustomerCardinvariant: owner.age >= 18

owner instància de Customer. owner.age de tipus Integer.

- Nota: CustomerCard no és el context “correcte” per a aquesta restricció, necessitem el Customer.

- Per això fem servir el nom que hi ha a l'extrem de Customer de l'associació entre CustomerCard i Customer, que és owner.

- Preferència: Sempre donar els noms de la funció (age).

23

LoyaltyProgram

enroll(c:Customer)

Service

condition: BooleanpointsEarned: IntegerpointsBurned: Integerdescription: String

0..*deliveredServices

Membership

LoyaltyAccount

points: Integer

earn(i: Integer)burn(i: Integer)isEmpty(): Boolean

Customer

name: Stringtitle:StringisMale: BooleandateOfBirth: Date

CustomerCard

valid: BooleanvalidFrom: DategoodThru: Datecolor: enum{silver, gold}printedName: String

0..*0..*

age(): Integer

programs

owner

cards0..*card

ProgramPartner(Empresa)

numberOfCustomers: Integer

partners

1..*

1..*

ServiceLevel

name: String

availableServices

0..*

{ordered} 1..*0..1

0..*

actualLevel

Transaction

points: Integerdate:Date

program(): LoyaltyProgram

0..*transactions

card

transactions0..*transactions

0..*

Burning Earning

Date

$now: Date

isBefore(t:Date): BooleanisAfter(t:Date): Boolean=(t:Date): Boolean

1

1

1

1

1

1

1

1

1

level

generatedBy

partner 1

account

24

Invariants amb navegació a traves d'extrems d'associació – Roles (2)

context CustomerCardinvariant printedName:printedName = owner.title.concat(' ').concat(owner.name)

printedName un String. owner instància de Customer. owner.title un String. owner.name un String. String és un tipus reconegut en OCL. concat és una operació de String, amb la

signatura: concat(String): String.

25

LoyaltyProgram

enroll(c:Customer)

Service

condition: BooleanpointsEarned: IntegerpointsBurned: Integerdescription: String

0..*deliveredServices

Membership

LoyaltyAccount

points: Integer

earn(i: Integer)burn(i: Integer)isEmpty(): Boolean

Customer

name: Stringtitle:StringisMale: BooleandateOfBirth: Date

CustomerCard

valid: BooleanvalidFrom: DategoodThru: Datecolor: enum{silver, gold}printedName: String

0..*0..*

age(): Integer

programs

owner

cards0..*card

ProgramPartner(Empresa)

numberOfCustomers: Integer

partners

1..*

1..*

ServiceLevel

name: String

availableServices

0..*

{ordered} 1..*0..1

0..*

actualLevel

Transaction

points: Integerdate:Date

program(): LoyaltyProgram

0..*transactions

card

transactions0..*transactions

0..*

Burning Earning

Date

$now: Date

isBefore(t:Date): BooleanisAfter(t:Date): Boolean=(t:Date): Boolean

1

1

1

1

1

1

1

1

1

level

generatedBy

partner 1

account

26

Invariants que usen navegació desde les classes d'associació

La navegació desde una classe d'associació cap a l'altra pot utilitzar el nom de la classe d'associació, o el nom de la funció.

L'objecte de context és la instància de classe d'associació - una tupla.

“El propietari de la targeta de membres ha de ser el client en l'afiliació”:context Membershipinvariant correctCard: card.owner = customer

27

LoyaltyProgram

enroll(c:Customer)

Service

condition: BooleanpointsEarned: IntegerpointsBurned: Integerdescription: String

0..*deliveredServices

Membership

LoyaltyAccount

points: Integer

earn(i: Integer)burn(i: Integer)isEmpty(): Boolean

Customer

name: Stringtitle:StringisMale: BooleandateOfBirth: Date

CustomerCard

valid: BooleanvalidFrom: DategoodThru: Datecolor: enum{silver, gold}printedName: String

0..*0..*

age(): Integer

programs

owner

cards0..*card

ProgramPartner(Empresa)

numberOfCustomers: Integer

partners

1..*

1..*

ServiceLevel

name: String

availableServices

0..*

{ordered} 1..*0..1

0..*

actualLevel

Transaction

points: Integerdate:Date

program(): LoyaltyProgram

0..*transactions

card

transactions0..*transactions

0..*

Burning Earning

Date

$now: Date

isBefore(t:Date): BooleanisAfter(t:Date): Boolean=(t:Date): Boolean

1

1

1

1

1

1

1

1

1

level

generatedBy

partner 1

account

28

Invariants que usen la navegació a través de classes d'associació

La navegació d'una classe a través d'una classe d'associació, utilitza el nom de classe d'associació per obtenir totes les tuples de l'objecte:

“Les targetes de soci d'un client són només les targetes dels clients”

context Customer

invariant correctCard:

cards->includesAll(Membership.card)

La següent restricció és exactament la mateixa que l'anterior:

“El propietari de la targeta de membres ha de ser el client membre”

context Membership

invariant correctCard: card.owner = customer

La segona restricció és millor!

29

LoyaltyProgram

enroll(c:Customer)

Service

condition: BooleanpointsEarned: IntegerpointsBurned: Integerdescription: String

0..*deliveredServices

Membership

LoyaltyAccount

points: Integer

earn(i: Integer)burn(i: Integer)isEmpty(): Boolean

Customer

name: Stringtitle:StringisMale: BooleandateOfBirth: Date

CustomerCard

valid: BooleanvalidFrom: DategoodThru: Datecolor: enum{silver, gold}printedName: String

0..*0..*

age(): Integer

programs

owner

cards0..*card

ProgramPartner(Empresa)

numberOfCustomers: Integer

partners

1..*

1..*

ServiceLevel

name: String

availableServices

0..*

{ordered} 1..*0..1

0..*

actualLevel

Transaction

points: Integerdate:Date

program(): LoyaltyProgram

0..*transactions

card

transactions0..*transactions

0..*

Burning Earning

Date

$now: Date

isBefore(t:Date): BooleanisAfter(t:Date): Boolean=(t:Date): Boolean

1

1

1

1

1

1

1

1

1

level

generatedBy

partner 1

account

30

Invariants que usen la navegació a través d'associacions amb multiplicitat múltiple

Navegació a través d'associacions amb multiplicitat més gran que 1 produeix un tipus de col·lecció.

Operacions sobre col·leccions:

- s'accedeix mitjançant una fletxa → , seguit pel nom d'operació.

“Una targeta de client (CustomerCard) pertany només a un membre que és el propietari (owner)”

context CustomerCard

invariant correctCard:

owner.Membership->includes(membership)

owner una instància de Customer.

owner.Membership un set d'instàncies de Membership.

membership una instància de Membership.

includes és una operació dels tipus OCL Collection.

31

LoyaltyProgram

enroll(c:Customer)

Service

condition: BooleanpointsEarned: IntegerpointsBurned: Integerdescription: String

0..*deliveredServices

Membership

LoyaltyAccount

points: Integer

earn(i: Integer)burn(i: Integer)isEmpty(): Boolean

Customer

name: Stringtitle:StringisMale: BooleandateOfBirth: Date

CustomerCard

valid: BooleanvalidFrom: DategoodThru: Datecolor: enum{silver, gold}printedName: String

0..*0..*

age(): Integer

programs

owner

cards0..*card

ProgramPartner(Empresa)

numberOfCustomers: Integer

partners

1..*

1..*

ServiceLevel

name: String

availableServices

0..*

{ordered} 1..*0..1

0..*

actualLevel

Transaction

points: Integerdate:Date

program(): LoyaltyProgram

0..*transactions

card

transactions0..*transactions

0..*

Burning Earning

Date

$now: Date

isBefore(t:Date): BooleanisAfter(t:Date): Boolean=(t:Date): Boolean

1

1

1

1

1

1

1

1

1

level

generatedBy

partner 1

account

32

Navegació en les col·leccions

context Customeraccount produeix un conjunt d'Accounts

context Customer

account.transaction produeix un bag de transactions

Si volem utilitzar això com un conjunt, hem de fer el següent:

account.transaction -> asSet

Customer Account Transaction0..* 0..*

33

Navegació en les col·leccions

“Els socis d'un programa de fidelitat tenen almenys un servei prestat”

context LoyaltyProgram

invariant minServices:

partners.deliveredServices->size() >= 1

“El nombre de programes d'un client és igual al nombre de targetes vàlides que té”

context Customer

invariant sizesAgree:

programs->size() = cards->select(valid=true)->size()

34

LoyaltyProgram

enroll(c:Customer)

Service

condition: BooleanpointsEarned: IntegerpointsBurned: Integerdescription: String

0..*deliveredServices

Membership

LoyaltyAccount

points: Integer

earn(i: Integer)burn(i: Integer)isEmpty(): Boolean

Customer

name: Stringtitle:StringisMale: BooleandateOfBirth: Date

CustomerCard

valid: BooleanvalidFrom: DategoodThru: Datecolor: enum{silver, gold}printedName: String

0..*0..*

age(): Integer

programs

owner

cards0..*card

ProgramPartner(Empresa)

numberOfCustomers: Integer

partners

1..*

1..*

ServiceLevel

name: String

availableServices

0..*

{ordered} 1..*0..1

0..*

actualLevel

Transaction

points: Integerdate:Date

program(): LoyaltyProgram

0..*transactions

card

transactions0..*transactions

0..*

Burning Earning

Date

$now: Date

isBefore(t:Date): BooleanisAfter(t:Date): Boolean=(t:Date): Boolean

1

1

1

1

1

1

1

1

1

level

generatedBy

partner 1

account

account

35

Navegació en les col·leccions

“Quan un programa de fidelitat (LoyaltyProgram) no ofereix la possibilitat de sumar o restar punts (pointEarned i pointsBurned), els membres del programa no tenen comptes de fidelitat.

És a dir, la taula comptes de fidelitat estarà buida.”

context LoyaltyProgram

invariant noAccounts:

partners.deliveredServices->

forAll(pointsEarned = 0 and pointsBurned = 0)

implies Membership.account->isEmpty()

36

LoyaltyProgram

enroll(c:Customer)

Service

condition: BooleanpointsEarned: IntegerpointsBurned: Integerdescription: String

0..*deliveredServices

Membership

LoyaltyAccount

points: Integer

earn(i: Integer)burn(i: Integer)isEmpty(): Boolean

Customer

name: Stringtitle:StringisMale: BooleandateOfBirth: Date

CustomerCard

valid: BooleanvalidFrom: DategoodThru: Datecolor: enum{silver, gold}printedName: String

0..*0..*

age(): Integer

programs

owner

cards0..*card

ProgramPartner(Empresa)

numberOfCustomers: Integer

partners

1..*

1..*

ServiceLevel

name: String

availableServices

0..*

{ordered} 1..*0..1

0..*

actualLevel

Transaction

points: Integerdate:Date

program(): LoyaltyProgram

0..*transactions

card

transactions0..*transactions

0..*

Burning Earning

Date

$now: Date

isBefore(t:Date): BooleanisAfter(t:Date): Boolean=(t:Date): Boolean

1

1

1

1

1

1

1

1

1

level

generatedBy

partner 1

account

account

37

Els tipus de col·leccions

Collection és un tipus predefinit

» Hi han operacions definides per les col·leccions

» Mai canvia l'original

Tres tipus diferents

» Set (no hi han duplicats)

» Bag (poden haver duplicats)

» Sequences (una Bag ordenada)

Una expressió OCL afirma un fet sobre tots els objectes de la col·lecció, o estableix un fet sobre la pròpia col·lecció (p.e.: la mida de la col·lecció)

Sintaxi: collection → operació

OCL 38

Operacions de les col·leccions

<collection> iterate(OclExpression)

isEmpty : Boolean

notEmpty : Boolean

size : Integer

συµ : Integer

count(Object) : Integer

forAll(OclExpression) : Boolean

select(OclExpression) : Collection

reject(OclExpression) : Collection

exist(OclExpression) : Boolean

OCL 39

Operacions de les Col·leccions

Exemples:

context Company invariant:

self.employee select (age > 50) notEmpty

self.employee reject (p | p.age <= 50) notEmpty

self.employee forAll (e1, e2 | e1 <> e2 implies e1.forename <> e2.forename)

self.employee exists (p: Person | p.forename = 'Jack')

OCL 40

Operacions de les Col·leccions

<Set> union(Set) : Set

intersection(Set) : Set

count(Object) : Integer

<Bag> intersection(Bag) : Bag

count(Object) : Integer

equal(bag) : Boolean

<Sequence> count(Object) : Integer

at(Integer) : T

first : Integer

41

Característiques de les classes

allInstance es un mètode de les classes que retorna el conjunt de totes les instancies d'aquella classe a l'hora d'avaluar

context Person invariant:

Person.allInstances forAll(p1,p2 | p1<>p2 implies p1.dni <> p2.dni)

42

Propietats predefinides en tots els objectes

OclIsTypeOf (t : OclType) : Boolean

OclIsKingOf (t : OclType) : Boolean

OclInState (s : OclState) : Boolean

OclisNew : Boolean

OclAsType (t : OclType) : instance of OclType

context Person invariant:

self.oclIsTypeOf( Person ) -- cert

self.oclIsTypeOf( Company ) -- fals

OCL 43

Canviant de context

Customer

showName:Stringpoint: Integer

1..*owner card

CustomerCardname:Stringtitle: Stringgolduser: Boolean

age( ):Integerearn(p:Integer)

context CustomerCardinvariant: showName = owner.title.concat(owner.name)

context Customercard forAll (showName = owner.title.concat(owner.name) )

Canvi de context!

OCL 44

Exemple dels estudiants i les matricules

matriculat

matriculatsEstudiant Assignatura

Valoració

Examen Treball

0..*1..*

1..*

1..*

0..*

per l'assignatura

puntua

repValoracio

rebuda per

nom: String codi: Stringcrèdits: Integer

pes: Integer

hores: Integer data: String

OCL 45

Exemple dels estudiants i les matricules

Les assignatures es poden agafar si i només si tenen més de set estudiants matriculats

Les avaluacions per assignatura han de ser 100%

Els estudiants s'han d'inscriure en 120 crèdits cada any

Els estudiants han de prendre un mínim de 90 crèdits de les assignatures troncals (T) cada any

Tots les assignatures han de tenir com a mínim un valor d'avaluació de més de 50%

Els estudiants només poden tenir les avaluacions de les assignatures que s'estan duent a treball

OCL 46

Exemple dels estudiants i les matricules

Les assignatures es poden agafar si i només si tenen més de set estudiants matriculats

− quan aquesta limitació ha de ser imposada?

context Assignatura

invariant: matriculatssize > 7

OCL 47

Exemple dels estudiants i les matricules

Les avaluacions per assignatura han de ser 100%

context Assignatura

invariant:

puntua.pessum( ) = 100

OCL 48

Exemple dels estudiants i les matricules

Els estudiants s'han d'inscriure en 120 crèdits cada any

context Estudiant

invariant: matriculat.crèditssum( ) = 120

OCL 49

Exemple dels estudiants i les matricules

Els estudiants han de prendre un mínim de 90 crèdits de les assignatures troncals (T) cada any

context Estudiant invariant: matriculat select(codi.substring(1,2) = ‘T’).crèdit → sum( ) >= 90

OCL 50

Exemple dels estudiants i les matricules

Tots les assignatures han de tenir com a mínim un valor d'avaluació de més de 50%

context Assignatures invariant:

puntuaexists(pes > 50)

OCL 51

Exemple dels estudiants i les matricules

Els estudiants només poden tenir les avaluacions de les assignatures que s'estan duent a treball

context Estudiant invariant: matriculatincludesAll(repValoracio.perAssignatura)

OCL 52

Navegació de les classes a través de les associacions cícliques

Navegar a traves de les associacions cícliques requereixen funcions per distingir els punts d'associacions:

object.associationClass[role]La puntuació acumulada d'un treballador és positiva:

context Persona invariant: rankingTreballador[cap].scoresum()>0

Cada cap ha de puntuar almenys un 10:

context Persona invariant: rankingTreballador[empleat]exists(puntuacio = 10)

Persona

rankingTreballador

*

*

cap

puntuació

empleat

OCL 53

Navegació a través de l'Associació qualificada

Per navegar a través de les associacions qualificades es necessita un index

object.navigation[qualifierValue, ...] Si n'hi han multiples qualificadors s'han de

separar per comes

Exemplecontext LoyaltyProgram

serviceLevel[1].name = ‘basic’

context LoyaltyProgram

serviceLevelexists(name = ‘basic’)

LoyaltyProgram

enroll(c:Customer)

ServiceLevel

name: String

0..1

levelNumber: Integer

54

LoyaltyProgram

enroll(c:Customer)

Service

condition: BooleanpointsEarned: IntegerpointsBurned: Integerdescription: String

0..*deliveredServices

Membership

LoyaltyAccount

points: Integer

earn(i: Integer)burn(i: Integer)isEmpty(): Boolean

Customer

name: Stringtitle:StringisMale: BooleandateOfBirth: Date

CustomerCard

valid: BooleanvalidFrom: DategoodThru: Datecolor: enum{silver, gold}printedName: String

0..*0..*

age(): Integer

program

owner

card0..*card

ProgramPartner(Empresa)

numberOfCustomers: Integer

partners

1..*

1..*

ServiceLevel

name: String

availableServices

0..*

{ordered} 1..*0..1

0..*

actualLevel

Transaction

points: Integerdate:Date

program(): LoyaltyProgram

0..*transactions

card

transactions0..*transactions

0..*

Burning Earning

Date

$now: Date

isBefore(t:Date): BooleanisAfter(t:Date): Boolean=(t:Date): Boolean

1

1

1

1

1

1

1

1

1

level

generatedBy

partner 1

account

OCL 55

Classes i subclasses

Considerem la següent regla:

context LoyaltyPrograminvariant: partners.deliveredServices.transaction

.pointssum() < 10000

Si la restricció només s'aplica a la subclasse Burning, podem utilitzar l'operació oclType:

context LoyaltyPrograminvariant: partners.deliveredServices.transaction

select(oclType = Burning).pointssum() < 10000

OCL 56

Classes i subclasses

“L'objectiu de la dependència no és la font

context Dependencyinvariant: self.source <> self

És ambigu

- La dependència és tant

un ModelElement com

una classe d'associació

context Dependencyinvariant: self.oclAsType(Dependency).source <> selfinvariant:

self.oclAsType(ModelElement).source isEmpty()

ModelElement

Note Dependency

*

*target

source

57

L'objectiu és conèixer un llenguatge de restriccions d'objectes: OCL, que forma part de l'UML.

És un conjunt de notacions precises de llenguatge textual per expressar restriccions que no poden ser expressades en l'UML.

La semàntica d'OCL s'aplica sobre la base de la construcció d'eines CASE que suporten comprovacions d'integritat sobre tots els models d'UML.

La semàntica d'OCL proporciona una semàntica per a les classes, associacions, atributs i els estats.

Conclusions

58

Amb els diagrames de l'UML no n'hi ha prou!

Volem un llenguatge que ens ajudi amb les especificacions.

Busquem una ampliació enlloc d'un llenguatge completament nou amb la capacitat d'especificació completa.

OCL – omple el buit que falta.

Especifica restriccions

No és l'únic, però és l'únic que està estandarditzat i forma part de l'UML.

Sintaxis intuitiva – com OO llenguatges.

No és un llengutge de programació: No hi ha control de fluxe No hi ha efectes col·laterals.

Conclusions

59

Referències

http://www.omg.org/spec/OCL/2.2/

OCL de Juan Casas, Universidad Politecnica de Valencia

http://www-2.dc.uba.ar/materias/isoft1/teoricas_2009_1/05b-ModeloConceptual_OCL_BN.pdf

http://www.itlalaguna.edu.mx/Academico/Carreras/sistemas/Analisis%20y%20dise%C3%B1o%20orientado%20a%20objetos/OCL.pdf

60

Referències

Exemples amb OCL

https://github.com/eclipse/ocl

Plugin eclipse

http://www.eclipse.org/modeling/mdt/?project=ocl

Linux

http://maude.cs.uiuc.edu/download/

http://maude.sip.ucm.es/itp/ocl/

http://maude.sip.ucm.es/itp/ocl/quick-tutorial.html

61

Preguntes ?