OCL - Linguagem para Especificação de Restrições em Objetos
Por Janderson Jason
(janderson.aguiar@ccc.ufcg.edu.br)
Modelar é essencial para desenvolver um software. Para isso, diagramas UML são amplamente utilizados na academia e no mercado. Para especificação de restrições, é possível fazer uso de OCL (Object Constraint Language). Revise, nesta matéria, alguns conceitos básicos dessa linguagem para especificar restrições em objetos.




Modelos precisam ser completos, precisos, testados e verificados. A UML (Unified Modeling Language), proposta para padronizar e unificar os artefatos em uma só linguagem para modelagem de sistemas orientados a objetos, não provê todos os aspectos relevantes da especificação do sistema, uma vez que restrições adicionais são escritas em linguagem natural, ao longo dos diagramas, o que pode facilmente gerar ambiguidade.

Para minimizar esse problema, existem linguagens formais tradicionais, mas que não possuem notação muito intuitiva, exigindo forte conhecimento matemático.

Em 1997, criada originalmente na IBM, foi lançada a OCL, sigla para Object Constraint Language, linguagem de expressões para especificar restrições sobre modelos orientados a objetos ou outros artefatos da linguagem UML, de fácil leitura/escrita e mais próxima da implementação de modelos.

A OCL é uma linguagem precisa, textual e formal, complementando a UML, uma vez que sua estrutura está fortemente vinculada a outros modelos da UML, como, por exemplo, diagramas de classes.

As expressões OCL são escritas em forma de afirmações e requerem um contexto de um modelo, que pode ser uma classe de objetos ou pode ser uma operação aplicável a um objeto. Para representar um contexto em OCL, utiliza-se a palavra reservada context.

OCL possui uma classificação hierárquica para os tipos de dados (Figura 1). Os tipos básicos são Integer, Real, Boolean e String. As coleções podem ser Collection, Set, Sequence e Bag. Os tipos especiais são OclAny, OclType e OclExpression. E, além desses, há os tipos dos modelos UML, que são todas as classes, interfaces, associações e enumerações introduzidas por um diagrama de classes.

Figura 1: Diagrama da hierarquia de classes em OCL.

A linguagem OCL é usada para especificar invariantes, descrever pré e pós-condições sobre operações e métodos, especificar corpo de operações, especificar regras dedutivas, especificar inicializações de propriedades, descrever guardas, e servir como linguagem de navegação. Nesta matéria, o foco será o exemplo de Invariantes.

Invariantes são condições que devem ser respeitadas pelos objetos modelados do sistema. Em OCL, para indicar que uma expressão é uma Invariante, utiliza-se a palavra reservada inv após a declaração do contexto. Na Figura 2, é apresentado um diagrama de classe usado nos exemplos de Invariantes a seguir. Usa-se um ponto para especificar o valor de uma propriedade de uma classe definida no diagrama; por exemplo, Cliente.nome e Cliente.idade().

Figura 2: Exemplo de Diagrama de Classe.

context Cliente inv:
        self.idade() >= 18

Invariante 1

context Cliente inv:
        idade() >= 18

Invariante 2

context c : Cliente inv idadeMinima:
        c.idade() >= 18

Invariante 3

context Cliente inv:
        pronomeTratamento = (if masculino = true
                             then 'Sr.'
                             else 'Sra.'
                             endif)

Invariante 4

context ProgramaFidelidade inv:
        cliente->forAll(c1, c2 | c1 <> c2 implies c1.rg <> c2.rg)

Invariante 5

Muitas outras Invariantes poderiam ser criadas com base no diagrama da Figura 2, mas essas já exemplificam algumas características pertinentes a comentar.

As Invariantes 1, 2 e 3 mostram formas diferentes de escrever a mesma Invariante: um cliente deve ter a idade maior ou igual a 18 anos. A diferença das duas primeiras está na utilização da palavra reservada self; seu uso explicita a referência a uma instância do contexto. Na Invariante 3, é mostrada a possibilidade de se usar uma variável (variável c do tipo Cliente) e de nomear uma Invariante (no caso, idadeMinima).

A Invariante 4, que define qual pronome de tratamento será utilizado dependendo do sexo do cliente, mostra como usar if-then-else em OCL. Há obrigatoriedade no uso dessas três palavras, além de endif no final da expressão. Em casos, em que não há necessidade do else, é utilizado o implies, presente na Invariante 5, cuja sintaxe x implies y implica que, se x é verdadeiro, considere y.

Nas coleções em OCL, é possível realizar várias operações, que são precedidas por '->' em vez de um ponto. Na Invariante 5, há a operação forAll, operação de interação que especifica uma condição que deve ser verdadeira para todas as instâncias da coleção (outras operações de interação em OCL são: select, reject, collect, exists, iterate, entre outras). Nessa Invariante, é especificada uma restrição de unicidade, na qual se compara o rg de todas as instâncias dos clientes de um programa de fidelidade, duas a duas (c1 e c2). No caso, clientes diferentes não podem possuir um mesmo rg.

Com OCL é possível tornar a modelagem mais precisa e clara para os desenvolvedores. Os exemplos acima são para fazer o leitor relembrar o poder dessa linguagem, sendo apenas pequenas amostras do que é possível fazer com OCL. Para mais detalhes e exemplos sobre OCL, você pode consultar as referências abaixo.

-----

Referências:

Material de aula da disciplina de Sistemas de Informação 2 do professor Franklin Ramalho;

LIMA, D. H. A. & MUSIAL, Rafael. Entendendo OCL - Apresentação e utilização da Object Constraint Language 1.1. Disponível em: http://techblog.desenvolvedores.net/wp-content/uploads/downloads/2011/04/ocl_artigo.pdf. Acesso em: 9 de julho de 2012

Jornal PETNews - Edição: Jeymisson Oliveira - Revisão: Iago Araújo e Joseana Fechine
Grupo PET Computação UFCG, 2012. All rights reserved.