Este documento fornece um resumo sobre a Linguagem de Restrição de Objetos (OCL):
1) OCL é uma notação usada na UML para definir restrições sobre objetos, permitindo especificar invariantes de classe, pré e pós-condições de métodos e guardas de transições.
2) OCL é fortemente tipada e permite expressar restrições de forma precisa e sem ambiguidades. As expressões em OCL não causam efeitos colaterais.
3) O documento descreve os principais conceitos da OCL,
Multi-core Parallelization in Clojure - a Case Study
OCL Linguagem Restrição Objeto
1. OCL: Object
Constraint Language
Setembro 2003
Eliane Martins - Instituto de Computação - UNICAMP
2. 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.
Eliane Martins - Instituto de Computação - UNICAMP 2
3. Tópicos
• O que é
• Tipos de restrições
• Expressões
• Tipos e operações
Eliane Martins - Instituto de Computação - UNICAMP 3
4. 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
Eliane Martins - Instituto de Computação - UNICAMP 4
5. 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
Eliane Martins - Instituto de Computação - UNICAMP 5
6. 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
Eliane Martins - Instituto de Computação - UNICAMP 6
7. 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
Eliane Martins - Instituto de Computação - UNICAMP 7
8. 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
Eliane Martins - Instituto de Computação - UNICAMP 8
9. OCL
• Exemplos de invariantes:
context Cliente
inv: idade > = 18 and self.idade < 100
objeto
context c: Cliente atributo
inv CasamentoLegal: c.casado implies c.idade > = 21
Identificador da invariante
Eliane Martins - Instituto de Computação - UNICAMP 9
10. OCL
• Invariantes sobre associações:
– invariantes de atributos conectados
Empregado
através de associações:
• referência: objeto.papel nome: string
• o valor da expressão pode ser: idade: integer gerente
– 1 objeto, se a multiplicidade da casado: boolean 1
associação é 0..1 ou 1 subordinado *
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
Eliane Martins - Instituto de Computação - UNICAMP 10
11. 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
Eliane Martins - Instituto de Computação - UNICAMP 11
12. 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
Eliane Martins - Instituto de Computação - UNICAMP 12
13. 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
cria ( )
pilha insere (item )
vazia pilha não insere (item) {self.nroItens = Max}
vazia
pilha
cheia
insere (item) {self.nroItens < Max}
Eliane Martins - Instituto de Computação - UNICAMP 13
15. 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
Eliane Martins - Instituto de Computação - UNICAMP 15
16. 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
Eliane Martins - Instituto de Computação - UNICAMP 16
17. 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
Eliane Martins - Instituto de Computação - UNICAMP 17
18. 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)
Eliane Martins - Instituto de Computação - UNICAMP 18
21. 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}
Eliane Martins - Instituto de Computação - UNICAMP 21
22. 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
Eliane Martins - Instituto de Computação - UNICAMP 22
23. 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
Eliane Martins - Instituto de Computação - UNICAMP 23
24. 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
Eliane Martins - Instituto de Computação - UNICAMP 24
25. 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
Eliane Martins - Instituto de Computação - UNICAMP 25
26. 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)
enum{masculino, feminino}
• 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’)
Eliane Martins - Instituto de Computação - UNICAMP 26
27. 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
Eliane Martins - Instituto de Computação - UNICAMP 27
28. 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’)
Eliane Martins - Instituto de Computação - UNICAMP 28
29. 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)
Eliane Martins - Instituto de Computação - UNICAMP 29
30. 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
Eliane Martins - Instituto de Computação - UNICAMP 30
31. 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
Eliane Martins - Instituto de Computação - UNICAMP 31
32. Navegação através de uma associação
Pessoa Empresa
écasado: Boolean 0..* empregado 0..* empregador nome: String
temEmprego: Boolean nroEmpregados: Integer
idade: Integer 0..1 mulher capital( )
prenome: String Emprego
sobrenome: String cargo: String
sexo: enum{fem, masc} dataInicio: Date
salario(data): Real salario: Real
0..1 marido
• 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) )
Eliane Martins - Instituto de Computação - UNICAMP 32
33. 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.: Þ resultado é convertido em um singleton
Pessoa
self.emprego -> collect(salario) -> sum
Eliane Martins - Instituto de Computação - UNICAMP 33
34. 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]
Pessoa
écasado: Boolean
temEmprego: Boolean
idade: Integer 0..1 mulher Pessoa:
prenome: String self.casamento [mulher].local
sobrenome: String
sexo: enum{fem, masc}
salario(data): Real
0..1 marido Casamento
local: String
data: Date
Eliane Martins - Instituto de Computação - UNICAMP 34
35. 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
Eliane Martins - Instituto de Computação - UNICAMP 35
36. 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]
Pessoa
Banco écasado: Boolean
numero: Integer temEmprego: Boolean
agencia: Integer cliente idade: Integer 0..1 mulher
prenome: String
sobrenome: String Banco:
nroConta: Integer
sexo: enum{fem, masc} self.cliente -- Set(Pessoa)
0..1
salario(data): Real self.cliente [4001155] -- 1 objeto
0..1 marido Pessoa com nro de conta dado
Eliane Martins - Instituto de Computação - UNICAMP 36
37. 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)
Eliane Martins - Instituto de Computação - UNICAMP 37
38. 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)
Eliane Martins - Instituto de Computação - UNICAMP 38