Eliane Martins - Instituto de Computação - UNICAMP
OCL: Object
Constraint Language
Setembro 2003
2
Eliane Martins - Instituto de Computação - UNICAMP
Referências • UML. “Object Constraint Language Specification”. Versão
1.1, set/1997
• “OCL: Object Constraint Language”. Transp de curso de
Jean-Marie Favre.
• “Object Constraint Language (OCL)”. Transp de curso de
Arif Khan.
3
Eliane Martins - Instituto de Computação - UNICAMP
Tópicos • O que é
• Tipos de restrições
• Expressões
• Tipos e operações
4
Eliane Martins - Instituto de Computação - UNICAMP
OCL: Object Constraint Language • Notação da UML utilizada para definir restrições sobre
objetos
• Permite especificar 4 tipos de restrições:
– invariantes de classe, pré e pós condições de métodos, guardas (de
transições)
• Características:
– expressões especificadas em OCL não têm qualquer efeito
colateral, ou seja:
• não causam mudança no estado do objeto
• não causam modificações nos modelos
• não alteram o fluxo de controle
5
Eliane Martins - Instituto de Computação - UNICAMP
OCL • Características (cont.):
– OCL é fortemente tipada:
• toda expressão tem um tipo
• termos usados na expressão têm de ser usados de acordo com seu tipo
– ex.: não se pode usar valor inteiro onde se espera um tipo string
– OCL é uma linguagem para especificação, não de programação
– OCL é formal:
• sintaxe bem definida
• semântica precisa, sem ambigüidades
– OCL também pode ser usada para navegar através das associações
6
Eliane Martins - Instituto de Computação - UNICAMP
OCL • Tipos de restrições:
– Invariantes (inv)
• condição (ou predicado) que se aplica a TODAS as classes (ou tipo ou
interface ou associação ou ...)
– Pré-condição (pre)
• condição que deve ser satisfeita antes da execução de uma operação
– Pós-condição (post)
• condição que deve ser satisfeita após a execução de uma operação
–Guarda
• condição que deve ser satisfeita para que uma transição de estado seja
efetuada
7
Eliane Martins - Instituto de Computação - UNICAMP
OCL
• Contexto
– elemento ao qual é uma restrição associada
• invariante: o contexto é a classe.
• Guarda: o contexto é uma transição do modelo de estado
– a restrição pode ser associada ao contexto de várias
formas:
• utilizar anotação em UML
• descrever na forma de texto:
– uso da palavra reservada context
– uso da palavra reservada self
8
Eliane Martins - Instituto de Computação - UNICAMP
OCL • Invariante
– condição associada a uma classe (ou tipo ou associação, ...)
– deve ser satisfeita a cada instante
– o contexto é definido por um objeto o qual
• pode ser referenciado por self
• pode ser nomeado explicitamente
– uma invariante pode ter um identificador
9
Eliane Martins - Instituto de Computação - UNICAMP
OCL • Exemplos de invariantes:
context Cliente
inv: idade > = 18 and self.idade < 100
context c: Cliente
inv CasamentoLegal: c.casado implies c.idade > = 21
Identificador da invariante
objeto
atributo
10
Eliane Martins - Instituto de Computação - UNICAMP
OCL
• Invariantes sobre associações:
– invariantes de atributos conectados
através de associações:
• referência: objeto.papel
• o valor da expressão pode ser:
– 1 objeto, se a multiplicidade da
associação é 0..1 ou 1
ex.: self.gerente -- é do tipo Empregado
– 1 coleção de objetos, se a multiplicidade
>1
ex.: self.subordinado -- é do tipo
conjunto {Empregado}
coleções serão abordadas mais para
frente
Empregado
nome: string
idade: integer
casado: boolean
1gerente
subordinado
*
11
Eliane Martins - Instituto de Computação - UNICAMP
OCL • Pré e pós condições
– condições (ou predicados) associadas a uma operação
– as pré condições devem ser satisfeitas antes da execução da
operação
– as pós condições devem ser satisfeitas após a execução da
operação
–self pode ser usada para designar o objeto cuja operação foi
chamada
–result pode ser usada para designar o resultado
–@pre permite fazer referência ao valor de um operando antes da
execução da operação
12
Eliane Martins - Instituto de Computação - UNICAMP
OCL • Exemplos de pré e pós condições:
context Pessoa :: faz_aniversario ( )
post: idade = idade@pre + 1
context Calculadora :: divisão_inteira (x:Integer, y: Integer)
pre regraDivisor: y ≠0
post: result = x / y
13
Eliane Martins - Instituto de Computação - UNICAMP
OCL •Guarda
– condição que deve ser satisfeita para que uma transição
do modelo de estados (Statecharts) ocorra
pré condição para a execução da transição
pilha não
vazia
pilha
cheia
pilha
vazia
cria ( )
insere (item )
insere (item) {self.nroItens = Max}
insere (item) {self.nroItens < Max}
15
Eliane Martins - Instituto de Computação - UNICAMP
OCL • Expressões
–constante
– identificador
–self
– expr op expr
– exprobj.propriedadeobj (parâmetros)
– exprcoleção.propriedadecoleção (parâmetros)
– pacote :: pacote :: elemento
–if condição then expr else expr endif
–let variável : tipo in expr Obs.: propriedade em OCL pode ser: atributo, operação, método, extremidade de
associação
16
Eliane Martins - Instituto de Computação - UNICAMP
OCL • Sobre as expressões:
– toda expressão tem um tipo e um valor
– constantes e identificadores podem ser usados em expressões
ex.: 12 nome salário
– uma expressão é referente a um elemento (contexto)
–. permite o acesso a uma propriedade (atributo ou operação) de um objeto
ex.: self.salário - 100 self.calculaImposto(2003)
–-> permite o acesso a uma propriedade de uma coleção de objetos
ex.: self.dependentes->size self.dependentes->isEmpty
–:: permite o acesso a elemento de um pacote
ex.: seja B subclasse de A
self.A :: p1 -- acesso a propriedade p1 definida em A
self.B :: p1 -- acesso a propriedade p1 definida em B
17
Eliane Martins - Instituto de Computação - UNICAMP
OCL - Tipos e operações •Inteiros (Integer)
– valores: 1, -5, 24345
– operações: +, -, *, div, mod, abs, max, min
• Reais (Real)
– valores: 1.5, 1.3456
– operações: +, -, *, /, floor, round, max, min
18
Eliane Martins - Instituto de Computação - UNICAMP
OCL - Tipos e operações
• Valor lógico (Boolean)
– valores: true, false
– operações: not, and, or, xor, implies, if-then-else-endif
–obs.:
• true or x é sempre verdadeiro, mesmo se x é indefinido
• false and x é sempre falso, mesmo se x é indefinido
exemplos:
(idade < 20 implies desconto = 25) and (idade >= 20 implies desconto =
15)
if idade < 20 then desconto = 25 else desconto = 15 endif
desconto = (if idade < 20 then 25 else 15 endif)
21
Eliane Martins - Instituto de Computação - UNICAMP
Tipos e operações •Coleções:
Em OCL pode-se ter 3 tipos de coleção:
– conjunto (Set): sem repetição, desordenado
• ex.: Set{1, 6, 90, 2, 0}
– “saco” (Bag): com repetição, desordenado
• ex.: Bag{203, 5, 40, 5, 300, 5}
– seqüência (Sequence): com repetição, ordenada
• ex.: Sequence{5, 5, 5, 40, 203, 300}
22
Eliane Martins - Instituto de Computação - UNICAMP
Uso de coleções •Os conjuntos são usados em UML:
– como extensões de classe, de associações
– como extremidade (endpoint) de uma associação
•As seqüências são usadas em UML:
– em associações com a restrição {ordered}
•Os “sacos” resultam da navegação em OCL:
– resultado da operação collect
– útil para operações como sum:
empregado -> collect(salario).sum
23
Eliane Martins - Instituto de Computação - UNICAMP
Operações sobre coleções • Operações básicas:
union, intersection, ...
• Operações de filtragem:
– seleção e eliminação de acordo com uma condição:
select, filter
• Imagem de uma função:
collect
• Quantificadores:
forall, exists
• Determinação de unicidade:
isUnique
24
Eliane Martins - Instituto de Computação - UNICAMP
Coleções: operações básicas Cardinalidade coleção -> size
Número de ocorrências coleção -> count(elem)
Pertence coleção -> includes(elem)
Não pertence coleção -> excludes(elem)
Inclusão col1 -> includesAll(col2)
Checa se vazio coleção -> isEmpty
Checa se não vazio coleção -> notEmpty
Soma de elementos coleção -> sum
25
Eliane Martins - Instituto de Computação - UNICAMP
Conjuntos: operações básicas União conj1 -> union (conj2)
Interseção conj1 -> intersection (conj2)
Diferença conj1 - conj2
Inclusão de elemento conj -> including(elem)
Exclusão de elemento conj -> excluding(elem)
Converte para seqüência conj -> asSequence
Converte para “saco” conj -> asBag
26
Eliane Martins - Instituto de Computação - UNICAMP
Coleção: filtragem • Seleção de elementos que satisfazem a uma condição:
coleção -> select(cond)
ex.: self.empregado->select(idade>55 and sexo = #masculino)
• Eliminação de elementos que satisfazem a uma condição:
coleção -> reject(cond)
ex.: self.aluno->reject( cr < 7)
• Outra sintaxe:
self.aluno -> reject (p:Pessoa | p.cidade_origem <> ‘Campinas’)
enum{masculino, feminino}
27
Eliane Martins - Instituto de Computação - UNICAMP
Coleção: imagem • Corresponde à imagem de um função em matemática:
coleção -> collect (expr)
– a expressão é avaliada para cada elemento da coleção
– o retorno da avaliação é um “saco” com os resultados
ex.:
self.empregados -> collect (idade) ≠ Bag{22, 37, 25, 22, 44, 52}
self.empregados -> collect (idade) -> asSet ≠ obtém conjunto
self.empregados -> collect (salário) -> sum
• pode-se escrever de forma simplificada:
self.empregados -> collect (idade) ↔ self.empregados.idade
28
Eliane Martins - Instituto de Computação - UNICAMP
Coleção: Quantificadores • Pode-se usar os quantificadores: ∀ e ∃
coleção -> forAll(cond)
retorna verdade se a cond é satisfeita por todos os elementos da coleção
coleção -> exists(cond)
retorna verdade se a cond é satisfeita por pelo menos um elemento da
coleção
ex.:
self.empregados -> forAll(idade < 55)
self.empregados -> exists(sexo = #feminino and idade > 50)
100 + if self.pessoa-> forAll (idade < 18) then 50
else self.pessoa -> select(idade >= 18) ->size * 5 endif
self.empregados-> exists( p: Pessoa | p.sobrenome = ‘Martins’)
29
Eliane Martins - Instituto de Computação - UNICAMP
Coleção: determinação de unicidade • Retorna verdade se para cada elemento da coleção
a expressão retorna um valor diferente:
coleção -> isUnique (expr)
– ex.:
self.alunos -> isUnique (prenome)
– útil para definir a noção de chave (identificador único)
30
Eliane Martins - Instituto de Computação - UNICAMP
Operações relativas ao diagrama de
classes • OCL oferece várias operações sobre o diagrama de classes:
– acesso a atributos e métodos
• acesso a um atributo: objeto.atributo
ex.: self.anodeProdução self.idade
• acesso a método: objeto.método(expr1, expr2, ...)
ex.: self.calcula_media(turma00)
– navegação pelas associações
– acesso a tipos e supertipos
– acesso às instâncias de uma classe
31
Eliane Martins - Instituto de Computação - UNICAMP
Navegação através de uma associação
• A partir de um objeto (contexto) é possível o acesso a
objetos que lhe são associados:
objeto.papel
– se cardinalidade 1 ou 0..1: o resultado é um objeto
– senão o resultado pode ser um conjunto (Set) ou uma seqüência
(Sequence) se associação tem restrição {ordered}
– se não tem papel em uma associação pode-se usar o nome da classe
destino com a primeira letra minúscula
32
Eliane Martins - Instituto de Computação - UNICAMP
Navegação através de uma associação
•Exemplos:
Pessoa self.marido -- é do tipo Pessoa
self.empregador -- é do tipo Set (Empresa)
self.marido-> nonEmpty implies self.marido.sexo = #masc
not ( (self.mulher -> size = 1 and (self.marido -> size = 1) )
0..1 mulher
0..1 marido
Pessoa
écasado: Boolean
temEmprego: Boolean
idade: Integer
prenome: String
sobrenome: String
sexo: enum{fem, masc}
salario(data): Real
Empresa nome: String
nroEmpregados: Integer
capital( )
0..* empregado0..* empregador
Emprego
cargo: String
dataInicio: Date
salario: Real
33
Eliane Martins - Instituto de Computação - UNICAMP
Navegação para uma associação • Se a associação é uma classe, pode-se ter acesso a ela
através de um objeto:
objeto.nome_da_associação
– o nome da associação deve iniciar com minúscula
– o resultado é exatamente 1 objeto, instância da classe referente à
associação
–ex.:
Pessoa
self.emprego -> collect(salario) -> sum
resultado é convertido em um singleton
34
Eliane Martins - Instituto de Computação - UNICAMP
Navegação para uma associação
• Se a associação (classe) é reflexiva, pode-se indicar o
papel para evitar ambigüidade:
– objeto.nome_da_associação [papel]
0..1 marido
Pessoa
écasado: Boolean
temEmprego: Boolean
idade: Integer
prenome: String
sobrenome: String
sexo: enum{fem, masc}
salario(data): Real
0..1 mulher
Casamento local: String
data: Date
Pessoa
:
self.casamento [mulher].local
35
Eliane Martins - Instituto de Computação - UNICAMP
Navegação a partir de uma associação • Pode-se navegar a partir da associação (classe) para os
objetos que ela relaciona:
nome_da_associação.papel
– o resultado da navegação será sempre 1 único objeto (que pode no
entanto ser convertido em singleton)
–exemplos:
Emprego
self.empregador
self.empregado
36
Eliane Martins - Instituto de Computação - UNICAMP
Navegação através de associação
qualificada • Associações qualificadas usam 1 ou + atributos para selecionar objetos
na outra ponta da associação
• Para navegar através dela, pode-se indicar um valor para o(s)
atributo(s) usado(s) como qualificador(es):
objeto.papel [valor]
0..1 marido
Pessoa
écasado: Boolean
temEmprego: Boolean
idade: Integer
prenome: String
sobrenome: String
sexo: enum{fem, masc}
salario(data): Real
0..1 mulher
nroConta: Integer
Banco
numero: Integer
agencia: Integer
cliente
0..1
Banco:
self.cliente -- Set(Pessoa)
self.cliente [4001155] -- 1 objeto
Pessoa com nro de conta dado
37
Eliane Martins - Instituto de Computação - UNICAMP
Operações sobre tipos
objeto.oclType
– retorna o tipo do objeto (pré-definido ou definido no
diagrama de classes)
objeto.oclIsTypeOf (tipo)
– retorna true seo tipo do objeto é exatamente tipo
objeto.oclIsKindOf (tipo)
– retorna true se o tipo do objeto é tipo ou algum de seus
supertipos
objeto.oclAsType (tipo)
– conversão de tipo (casting)
38
Eliane Martins - Instituto de Computação - UNICAMP
Operações sobre classes
classe.propriedade_da_classe
– permite o acesso a propriedades (características) da classe:
classe.allInstances retorna o conjunto de instâncias da classe
• ex.:
Pessoa.allInstances -> size < 500
Pessoa.allInstances -> forall (p1, p2 | p1 <> p2 implies p1.sobrenome <>
p2.sobrenome)
Banco.allInstances -> isUnique (numero)