OCL – The Object
Constraint Language
Franklin Ramalho
PhD Student – CIn - UFPE
Roteiro
Motivação
 Introdução
 Tipos e instâncias
 Herança
 Estilos para especificação em OCL
 Questões de modelagem com OCL
 Considerações Finais

Motivação




UML não provê todos aspectos relevantes da
especificação do sistema
Linguagem Natural é ambigua
Linguagens formais requerem forte conhecimento
matemático
OCL - Linguagem para escrita de restrição sobre
objetos, que pode ser aplicada em um ou mais
valores de um (ou parte de) sistema ou modelo
orientado a objetos.
Introdução





Linguagem formal de fácil escrita e leitura
Não é uma linguagem de programação
Sem efeitos colaterais
Linguagem tipada
Avaliação instântanea
Introdução

Uso de OCL:
– Especificar invariantes
– Descrever pre e pos condições sobre operações e
métodos
– Descrever guardas
– Servir como linguagem de navegação
Invariantes


É uma expressão cujo resultado deve ser verdadeiro
para todas as instâncias da classe, tipo ou interface
associada
Exemplo:
Context c : Customer inv MinimumAge:
c.age() >= 18
Context Customer inv:
self.age() >= 18

Podem ser representadas através:
–
–
–
–
Nota no modelo UML
Estereótipo <<invariant>>
Arquivo separado
Tab específico provido por ferramentas
Invariantes

Exemplo:
Context membership inv:
card.owner = customer
Context CustomerCard inv:
printedName = customer.title.concat (customer.name)
Invariantes
Pre e pos-condições


Pré-condição é uma restrição que deve ser verdadeira no
inicio da execução da operação.
Pós-condição é uma restrição que deve ser verdadeira no final
da execução da operação.
Context Typename::operationName (param1 :
Type1, ...) : ReturnType
pre: param1 > ...
post: result = ...
Context LoyaltyAccount::isEmpty() : Boolean
pre: -- none
post: result = ( points = 0)
Context LoyaltyProgram::enroll(c : Customer)
pre: not customer->includes(c)
post: customer = customer@pre->including(c)
Pre e pos-condições

Podem ser representadas através:
– Nota no modelo UML
– Estereótipos <<precondition>> e
<<poscondition>>
– Arquivo separado
– Tab específico provido por ferramentas
Tipos e instâncias

Tipos Valor
– Tipos Básicos
•
•
•
•
Integer
Real
String
Boolean
– Tipos Collection
•
•
•
•

Set
Bag
Sequence
Collection
Tipos Objeto
– Tipos Modelo (classes, interfaces ou tipos definidos no
modelo UML)
Tipos e instâncias

OCLAny é o supertipo de todos os tipos
–
–
–
–
–
–
=
<>
oclType
oclIsKindOf(type : OclType)
oclIsTypeOf(type : OclType)
oclAsType(type : OclType)
Context Burning inv:
self.oclType = Burning
self.oclIsKindOf(Transaction) = true
self.oclIsTypeOf(Transaction) = false
self.oclIsTypeOf(Burning) = true
Tipos e instâncias

OCLType é o supertipo de todos os tipos
–
–
–
–
–
name : String
attributes : Set (String)
associationEnds : Set (String)
operations : Set (String)
allInstances : Set(sometype.oclType)
Customer.name = ‘Customer’
Transaction.attributes = Set {‘points’, ‘date’}
Transaction.associationEnds = Set
{‘servicelevel’, ‘loyaltyAccount’, ‘card’}
Transaction.operations = Set {‘program’}
Tipos Básicos

Boolean
Context Customer inv:
Context Customer inv:
title = (if isMale = true
age() > 21 and age() < 65
then ‘Mr.’
else ‘Ms.’
endif)
Context Service inv:
self.pointsEarned > 0 implies self.pointsBurned = 0
Tipos Básicos

Integer e Real
2654 * 4.3 + 101 =11513.2
1.175 * (-8.9).abs – 10 = 0.4575
12.max(33) = 33
33.max(12) = 33
33.7.min(12) = 12
13.mod(2) = 1

String
‘casa’.size = 6
‘casa’.toUpper = ‘CASA’
‘casa’.concat(‘mento’) = ‘casamento’
Tipos Collection


Collection - supertipo abstrato usado para definir
operações comuns entre todos os tipos Collection
(Set, Bag e Sequence)
Operações:
–
–
–
–
–
–
–
–
–
–
–
size
count(object)
includes(object)
includesAll(collection)
isEmpty
notEmpty
sum()
exists(expression)
forAll(expression)
including(object)
excluding(object)
LoyaltyProgram
1..n
enroll()
+partners 1..n
ProgramPartner
numberOfCustomers : Integer
1..n
ServiceLevel
name : String
Context LoyaltyProgram inv:
serviceLevel->size = 2
LoyaltyProgram
1..n
enroll()
Context ServiceLevel inv:
loyaltyProgram.partners ->
+partners 1..n
ProgramPartner
numberOfCustomers : Integer
includesAll(availableServices.progr
amPartner)
ServiceLevel
name : String
1..n
0..n
+deliveredServices
Service
condition : Boolean
pointsEarned : Integer +availableServices
pointsBurned : Integer 0..n
description : String
Context LoyaltProgram inv:
partners.deliveredServices->forAll ( pointsEarned = 0 and
pointsBurned = 0) implies membership.loyaltyAccount->isEmpty
Tipos Collection

Tipo Set
– Subtração (-)
Set{1, 4, 7, 10} – Set {4, 7} = Set {1, 10}
– Diferença simétrica
Set{1, 4, 7, 10}.symmetricDifference(Set{4, 5, 7}) = Set{1, 5, 10}

Tipo Sequence
– first, last, at, append e prepend.
Sequence{1, 4, 7, 10}->first = 1
Sequence{1, 4, 7, 10}->last = 10
Sequence{1, 4, 7, 10}->at(3) = 7
Sequence{1, 4, 7, 10}->append( 15 ) = Sequence{15, 1, 4, 7, 10}
Sequence{1, 4, 7, 10}->prepend( 15 ) = Sequence{1, 4, 7, 10, 15}
Tipos Collection
Context ProgramPartner inv:
numberOfCustomers = loyaltyProgram.customer->size
Context ProgramPartner inv:
numberOfCustomers = loyaltyProgram.customer>asSet->size
Tipos Collection

Operações de interação
– select
Context CustomerCard inv:
self.trasactions->select( points > 100 )
–reject
– collect
Context LoyaltyAccount inv:
transaction->collect (points)-> exists (p: Integer | p = 500)
Tipos Collection

Iterate
collection->iterate( element : Type1;
result : Type2 = <expression>
| <expression-with-element-and-result>)
– iterate
Context ProgramPartner inv:
self.service.transaction->iterate(
t: Transaction;
result: Integer = 0 |
if t.oclType = Burning then
result + points
else
result
endif
)
Tipos Modelo


Classes (inclusive, classes-associação), tipos e
interfaces definidos no modelo UML, são
consideradas classes em OCL.
Estes tipos possuem propriedades:
–
–
–
–

Atributos
Operações e métodos
Navegações (associações)
Enumerações (definidas como tipo de algum atributo)
Exemplos: Service, ProgramPartner, Customer, etc.
Enumeration {silver, gold} definida na classe
CustomerCard.
Tipos Modelo

Navegações são tratadas como atributos cujos tipos
são tipos modelo ou collections
– Se a multiplicidade é no máximo 1, o tipo é modelo
Context CustomerCard inv:
self.owner.age() > 18
– Se a multiplicidade > 1, o tipo é collection
Context Customer inv:
self.cards->size = 1
Tipos Modelo

Navegação em classes-associação
Context Membership inv:
program.serviceLevel->includes
(actualLevel)
Context LoyaltyProgram inv:
serviceLevel->includesAll (
membership.actualLevel)
Restrições e Herança

Principio Liskov:
“Onde quer que uma instância de uma classe seja
esperada, ela pode ser substituída por uma instância
de alguma de suas sub-classes”

Na redefinição de uma restrição em uma sub-classe:
– Uma invariante pode ser fortalecida, não enfraquecida
– pré-condição deve ser enfraquecida, não fortalecida
– Pós-condição deve ser fortalecida, não enfraquecida
Restrições e Herança
Context Stove inv:
temperature <= 200
Context ElectricStove inv:
temperature <= 300
Context Stove inv:
temperature <= 150
Restrições e Herança
Context Stove::open()
pre: #off
post: status = #off and isOpen
Context ElectricStove::open()
pre: #off
post: status = isOpen
Context ElectricStove::open()
pre: temperature <= 50
post: status = #off and isOpen
Estilos para especificação OCL

Escolha correta do objeto Context
+husband Person +employees
0..1
0..n
wife 0..1
+employers
0..n
Company
Context Person inv:
wife.employers->intersection (self.employers)->isEmpty
and
husband.employers->intersection (self.employers)->isEmpty
Context Company inv:
employees.wife->intersection(self.employees)->isEmpty
Estilos para especificação OCL

Dividir uma restrição em várias
Context ProgramPartner inv:
partners.deliveredServices->forAll(pointsEarnerd = 0)
and membership.card->forAll(goodThru = Date.fromYMD(200.1.1))
and customer->forAll(age() > 55)
Context ProgramPartner inv:
partners.deliveredServices->forAll(pointsEarnerd = 0)
Context ProgramPartner inv:
membership.card->forAll(goodThru = Date.fromYMD(200.1.1))
Context ProgramPartner inv:
customer->forAll(age() > 55)
Estilos para especificação OCL

Adicionar atributos ou operações extras
Estilos para especificação OCL
Context Membership inv:
program.partners.deliveredServices->forAll(pointsEarned = 0)
implies LoyaltyAccount->isEmpty
Context LoyaltyProgram inv:
isSaving = partners.deliveredServices->forAll(pointsEarned = 0)
Context Membership inv:
program.isSaving implies LoyaltyAccount->isEmpty

Evitar expressões de navegação complexa
Questões de modelagem com
OCL

Especificar Restrições de unicidade
Context Person inv:
person.allInstances->forAll(p1, p2 | p1 <> p2 implies
p1.socialSecurityNumber <>
p2.socialSecurityNumber
Questões de modelagem com
OCL

Adicionar detalhes ao modelo versus adicionar
restrições
+strings GuitarString
Guitar
0..1
0..n
Electric
Guitar
+strings MetalString
0..1
0..1
+strings PlasticString
ClassicGuitar
0..1
0..n
+strings GuitarString
Guitar
0..1
Electric
Guitar
0..n
MetalString
ClassicGuitar
Context ClassicGuitar inv:
strings->forAll(oclType = PlasticString)
Context ElectricGuitar inv:
strings->forAll(oclType = MetalString)
PlasticString
Context Guitar inv:
type = #classic implies strings->forAll(type = #plastic)
Context Guitar inv:
type = #electric implies strings->forAll(type = #metal)
Questões de modelagem com
OCL

Restrição or
0..1
projectLeader
Person
0..1
0..1
{or}
projectMember
managedProject
Project
0..1
performedProject
Questões de modelagem com
OCL
0..1
projectLeader
Person
0..1
0..1
Project
projectMember
0..1
performedProject
Context Person inv:
managedProject->isEmpty or performedProject->isEmpty
Context Project inv:
projectLeader->isEmpty or projectmember->isEmpty
Considerações Finais

OCL é uma linguagem que expressa informação
extra em modelos.
–
–
–
–
–
–

Formal
Fácil de ler e escrever
Declarativa
Sem efeitos colaterais
Tipada
Adotada pela OMG como parte de UML.
Extensões
–
–
–
–
–
–
Novos tipos
Novas operações
O que fazer quando uma restrição for violada
Geração de código (?)
Outros diagramas: de estados, sequência,etc
Ferramentas que permitam geração de código (?)
Download

OCL