Object Constraint Language
Philip Stephen Medcraft
Sumário
Introdução
Ligação com a UML
Tipos básicos e operações
Objetos e propriedades
Operações em coleções
Introdução
Modelos gráficos são completos?
Podemos gerar especificações precisas
apenas com modelos gráficos?
Muitas vezes, sentimos a necessidade
de adicionar restrições aos objetos.
Uma linguagem natural pode resolver?
Uma linguagem formal é mais precisa!
Introdução
OCL é uma linguagem descritiva.
Uma expressão OCL não pode alterar
nada no esquema.
O estado do sistema nunca mudará
devido a uma expressão OCL.
Quando executada, uma expressão OCL
simplesmente devolve um valor.
Introdução
A OCL pode ser usada com diferentes
propósitos:
Para especificar restrições em classes e
tipos no diagrama de classes.
Para descrever pré e pós condições para
métodos.
Como uma linguagem de navegação.
Ligação com a UML
Uma expressão OCL:
´Essa é uma expressão OCL’
O contexto para a expressão:
NomeDoTipo
´Expressão OCL no contexto de NomeDoTipo’
Uma expressão OCL é escrita no
contexto de uma instância de um tipo
específico.
Ligação com a UML
Em uma expressão OCL, o nome self é usado
para referenciar o contexto.
Exemplo:
Company
self.numberOfEmployees
Outra opção:
c : Company
c.numberOfEmployees
Ligação com a UML
Pré e Pós condições:
A expressão é uma pré ou pós condição
para uma operação.
Portanto, a instância atual (contexto) é
do tipo que possui a operação.
Person::income(d : Date) : Integer
post: result = ... Alguma função ...
Tipos básicos e operações
Boolean (and, or, not, implies, if-then-else)
Integer (*, +, -, /, abs)
Real (*, +, -, /, floor)
String (toUpper, concat)
Collection
Set
Bag
Sequence
Tipos básicos e operações
Cada expressão OCL é escrita no
contexto de um modelo UML contendo:
um número de classes;
associações entre as classes;
generalizações.
Todos as classes do modelo UML são
tipos nas expressões OCL anexadas ao
modelo.
Tipos básicos e operações
Relações entre tipos:
Os tipos básicos são organizados numa
hierarquia.
Uma expressão OCL é válida quando os
seus tipos conformam. Caso contrário,
temos um “type conformance error”.
Tipos básicos e operações
Os relacionamentos entre os tipos
devem obedecer as seguintes regras:
Cada tipo conforma com seu supertipo;
Se tipo1 conforma com tipo2, e tipo2
conforma com tipo3, então tipo1 conforma
com tipo3.
Tipos básicos e operações
Casting:
Algumas vezes precisamos usar uma
propriedade de um objeto que é definido
num subtipo do objeto corrente.
object.oclAsType(Tipo2)
Neste exemplo, object é do tipo Tipo1.
Só podemos fazer o cast para um subtipo
do tipo corrente.
Objetos e propriedades
Propriedades:
O valor de uma propriedade de um objeto
definido num diagrama de classes é
especificado da seguinte forma:
UmTipo
self.nomePropriedade
Objetos e propriedades
Atributos
A idade de uma pessoa é escrita como:
Person
self.age
O tipo dessa expressão é o tipo do atributo
age (Integer).
Poderíamos definir como regra:
Person
self.age >= 0
Objetos e propriedades
Operações
Cada operação pode ser definida por uma
restrição de pós-condição.
Person::income (d : Date) : Integer
post: result = -- alguma função --
Para o caso de uma operação sem
parâmetros:
Company
self.stockPrice()
Objetos e propriedades
Navegação
Partindo de um certo objeto, podemos
navegar numa associação do diagrama de
classes, para referenciar outros objetos e
suas propriedades.
Company
self.manager -- do tipo Person
self.employee-- do tipo Set(Person)
Objetos e propriedades
Navegação
A execução da primeira expressão resultará
num objeto do tipo Person.
A execução da segunda expressão
resultará num conjunto de Pessoas.
Por default, navegação sempre resulta num
conjunto. No caso da associação conter o
elemento {ordered}, a navegação resulta
numa sequência.
Objetos e propriedades
Os tipos Set, Bag e Sequence são prédefinidos em OCL. Cada um desses
tipos de coleção possui um grande
número de operações pré-definidas.
Temos acesso a uma propriedade de
uma coleção usando uma seta ‘->’,
seguida do nome da propriedade.
Objetos e propriedades
A expressão abaixo resulta no número de
empregadores da Pessoa self.
Person
self.employer->size
A expressão abaixo resulta em ‘true’ caso o
conjunto de empregadores é vazio.
Person
self.employer->isEmpty
Objetos e propriedades
Alguns exemplos de expressões OCL:
self.wife->notEmpty implies self.wife.age >=18 and
self.husband->notEmpty implies self.husband.age >= 18
self.employee->size <= 50
self.wife.sex = #female and self.husband.sex = #male
not ((self.wife->size = 1) and (self.husband->size = 1))
Objetos e propriedades
Navegação para classes de associação:
OCL usa um ponto e o nome da classe de
associação iniciando com letra minúscula.
Person
self.job
Resulta no conjunto de todos os empregos
que a pessoa possui dentre as empresas.
Objetos e propriedades
Navegação:
Podemos ainda fazer uma melhor seleção dos
objetos. Veja os exemplos:
Bank
self.customer -- resulta num Set(Person) contendo
-- todos os clientes do banco.
self.customer[8764423] -- resulta numa pessoa
que possui número da
conta igual a 8764423
Objetos e propriedades
Coleções:
O tipo coleção é pré-definido em OCL.
Define um grande número de operações
pré-definidas que possibilitam ao autor
manipular coleções.
Collection é um tipo abstrato, com os tipos
concretos de coleções sendo:
• Set, Sequence, e Bag.
Objetos e propriedades
Set
É o conjunto matemático.
Não contém elementos duplicados.
Bag
É como Set, mas pode conter elementos
duplicados.
Sequence
É como Bag, com elementos ordenados.
Objetos e propriedades
Podemos obter coleções das seguintes
maneiras:
Definindo de forma direta:
• Set {1, 2, 3, 5, 7, 11, 13, 17}
• Sequence {1, 2, 3, 5, 7, 11, 13, 17}
• Bag {1, 2, 3, 2, 1}
Através de uma navegação:
Company
self.employee
Operações em coleções:
collection1->union(collection2)
Operações em coleções
Operação Select
Muitas vezes queremos apenas um
subconjunto de uma coleção.
O Select é uma operação realizada sobre
uma coleção, com a seguinte sintaxe:
Company
self.employee->select (age > 50)
Company
self.employee->select (p | p.age > 50)
Company
self.employee->select (p : Person | p.age > 50)
Operações em coleções
Operação Reject
Idêntica ao Select, no entanto, o subconjunto
que pegamos da coleção é composta pelos
elementos que não satisfazem à expressão.
As duas expressões abaixo são iguais:
Collection->reject ( v : Tipo | expressão-booleana )
Collection->select ( v : Tipo | not (expressão-booleana) )
Operações em coleções
Operação Collect
Usamos a operação quando queremos
especificar uma coleção a partir de uma outra,
mas com diferentes objetos da coleção original.
Company
self.employee->collect (birthDate)
self.employee->collect (person | person.birthDate)
self.employee->collect (person:Person |
person.birthDate)
Operações em coleções
Operação ForAll
Muitas vezes uma restrição é comum para
todos os elementos de uma coleção.
ForAll resulta num boolean. Retornará true
caso a restrição seja comum a todos.
Company
self.employee->forAll ( sobrenome = ‘Schiel’ )
Será true, caso todos os empregados da
empresa tenham sobrenome “Schiel”.
Operações em coleções
Operação Exists
Muitas vezes precisamos saber se há pelo
menos um elemento de uma coleção para
o qual uma certa restrição é válida.
Company
self.employee->exists ( sobrenome = ‘Schiel’ )
Será true, caso exista pelo menos um
empregado da empresa com sobrenome
“Schiel”.
Operações em coleções
Operação Iterate
A sintaxe é a seguinte:
collection->iterate ( elem : Tipo; acc : Tipo = <expressão> |
expressão-com-elem-e-acc )
collection->collect ( x : T | x.propriedade )
é idêntico a:
collection->iterate ( x : T; acc : T2 = Bag{} |
acc->including(x.property) )
Download

ObjectConstraintLanguage