Está en la página 1de 34

OCL

(Object Constraint Langauge)

Alcance:

Visin OCL en el modelado de software. o Fundamentos y aplicacin del lenguaje o Aplicacin de frmulas bsicas para definir restricciones a nivel de

estructura interna de los objetos del dominio.


o Integracin de OCL en artefactos modelados con UML.

Fundamentos y aplicacin del lenguaje

Modelo Definicin: Los Modelos se expresan mediante diagramas, se utilizan para mostrar e indicar informacin de inters, para lo cual hacemos uso de un conjunto consistente y coherente de elementos interrelacionados, que tienen caractersticas, condiciones y restricciones. OCL Definicin El lenguaje de Restriccin de Objetos OCL (Object Constraint Langauge) es un lenguaje de modelamiento con el cual es posible construir modelos de software, que permitan definir restricciones, caractersticas y condiciones del contexto en estudio. Haciendo uso del lenguaje es posible especificar expresiones que agregan informacin vital a los modelos orientados a objetos. OCL es el lenguaje standard a partir del cual estas expresiones se pueden escribir de una manera clara y no ambigua. Por consiguiente, los modelos debern ser buenos, slidos, consistentes y coherentes. Aplicando la combinacin de UML y OCL es posible construir modelos que renen buenas caractersticas y definiciones. OCL no es un lenguaje de programacin. OCL es un lenguaje typado, donde una cada expresin define un tipo. OCL es un lenguaje de especificaciones. Por qu usar OCL? Un Diagrama UML, tal como un Diagrama de Clases no es refinado para describir todos los aspectos relevantes de una especificacin, adems de no poder (por restricciones en el modelado de UML) definir restricciones adicionales sobre ciertos objetos en el Modelo. Estas definiciones se cubran mediante el uso del lenguaje natural, obteniendo resultados ambiguos y poco formales. Con estos aspectos descriptos y teniendo en cuenta que los modelos desarrollados eran usados por personas con una base slida de conocimiento

matemtico y muy poco de conocimiento sobre modelos de negocios, donde se encuentran y definen las reglas de negocio. OCL se cre para cubrir estos aspectos, generando un modelo fcil de leer y escribir con orientacin a crear un modelo que contemplen las reglas de negocio de una organizacin y/o Sistemas. Dnde usar OCL? Puede ser usado en diferentes propsitos: a) Como un Lenguaje de Consulta. b) Para especificar invariantes en las clases y tipos en el Modelo de Clases. c) Para especificar invariantes en los Estereotipos. d) Para describir pre y post condiciones en Operaciones y Mtodos. e) Para describir Guardas. f) Para especificar conjuntos de mensajes y acciones. g) Para especificar restricciones en operaciones. h) Para especificar reglas de derivacin para atributos de cualquier expresin provenientes de un Modelo UML.

Aplicacin de frmulas bsicas para definir restricciones a nivel de estructura interna de los objetos del dominio.

El contexto de una expresin de OCL: Cada expresin escrita en OCL hace uso de tipos (clases, interfaces, etc.) que estn definidos en los diagramas UML. La definicin de contexto de una expresin OCL especifica la entidad del modelo para el cual la expresin OCL esta definida. Usualmente esta es una clase, una interfaz, un tipo de dato, o un componente. Utilizaremos un trmino de UML estandard, denominado Clasificador para indicar con el que nos referimos a una clase, una interfaz, un tipo de dato o un componente. Tipos de expresiones OCL Las expresiones OCL se escriben utilizando caracteres ASCII. Las expresiones OCL sern escritas en este documento con tipo de letra sans serif. A continuacin de la palabra reservada context se detalla el nombre de un tipo para determinar el contexto de la expresin. context TypeName 'esto es una expresin OCL en el contexto de TypeName' Cada expresin OCL se escribe en el contexto de una instancia de un tipo especfico, utilizando el nombre SELF para referir a la instancia contextual. El nombre reservado SELF se refiere al objeto ocurrente (similar a this en C++ o Java). Nota: natural. Especificando el contexto en UML El contexto de una expresin OCL se puede especificar a partir de la declaracin del contexto al comienzo de la expresin OCL. Si la restriccin se muestra en el diagrama, con el propio estereotipo y lneas punteadas para conectar a su contexto, no hay La instancia contextual es el punto principal para la interpretacin (entendibilidad) de una expresin OCL. Semejante al sujeto de una oracin en lenguaje

necesidad de una declaracin explcita del contexto en la restriccin. Es decir, la declaracin del contexto es opcional. Por ejemplo, si el contexto es el tipo Company de la figura 1, la siguiente expresin especificar un invariante representando que el nmero de empleados debe exceder siempre a 50.

self.numOfEmployees > 50
Invariantes Las expresiones OCL pueden ser parte de un Invariante, el cual es una restriccin estereotipada con <<invariant>>. Cuando el invariante est asociado con un Clasificador 1, ste es llamado el tipo en este documento. La expresin entonces es un invariante del tipo y debe ser verdadero para todas las instancias de tal tipo en todo momento. La siguiente expresin OCL se aplica al diagrama de la figura 1:

context Compaa inv: self.nmeroDeEmpleados > 50

FIGURA 1:

Ejemplo de un diagrama de clases para una Compaa.

El tipo de la instancia contextual, se escribe a continuacin de la palabra reservada context, en este caso self es una instancia del tipo Compaa. Es posible ver a self como el objeto a partir del cual se define la expresin. La etiqueta inv: declara una expresin invariante. En muchos casos, la instancia contextual (self) se omite, debido a que el contexto es claro. Como una alternativa para self, es posible definir un nombre diferente para representar a self, como se muestra a continuacin:

context c: Compaa inv: c.nmeroDeEmpleados > 50


Definiendo el Contexto Definir el modelo, paquetes y alcance de una expresin:

Modelo mi_modelo - OCL Especificacin Paquete mi_paquete contexto Class1 inv ... (invariante o lo que sea) contexto Class1::operacin1(v1: Integer) inv ... finpaquete finmodelo
El contexto puede ser definido para cualquier elemento del modelo (paquetes, clases, interface, componentes) o para algunos subelementos como por ejemplo una operacin, atributo, y en algunos casos (por ejemplo diagrama de interaccin) como una instancia. Tipo de Expresiones OCL Este ltimo ejemplo es semnticamente idntico al anterior. Opcionalmente es posible nombrar la restriccin para permitir que la restriccin sea referida por su nombre. El nombre de la restriccin se escribe luego de la palabra reservada

inv.

En

el

siguiente

ejemplo

la

restriccin

es

denominada

enoughEmployees. context c: Company

inv enoughEmployees: c.numberOfEmployees > 50


Pre- y Post- Condiciones La expresin OCL puede ser parte de una Precondicin o Postcondicin, la cuales son restricciones estereotipadas con <<precondition>> <<postcondition>>. La precondicin o postcondicin es aplicable en Operaciones o Mtodos. En este caso, la expresin es una pre-/post-condicin en la operacin o mtodo. La instancia contextual

self es entonces del tipo que es dueo de la operacin.


La declaracin del contexto utiliza la palabra reservada context, seguido por el tipo y la declaracin de la operacin. El estereotipo de restriccin se muestra anteponiendo las etiquetas

pre:

post:

antes

de

las

precondiciones

postcondiciones respectivamente. context Typename::operationName(parameter1 : Type1, ...):

ReturnType pre : parameter1 > ... post : result = ...


El nombre self puede ser utilizado en la expresin para referir al objeto en el cual la operacin est definida, y el nombre result es el nombre del objeto retornado, si existe alguno. Los nombres de los parmetros (parameter1, ...) tambin pueden ser utilizados en expresiones OCL.

context Person:: income(d: Date) : Integer post : result = ...._alguna funcin de self y los parmetros.
Opcionalmente, el nombre de la precondicin o postcondicin puede ser escrita luego de las palabras reservadas pre o post, permitiendo que la restriccin sea referida por su nombre. En el siguiente ejemplo el nombre de una precondicin es

parameterOk, y el nombre de la postcondicin es resultOk. context Typename:: operationName(parameter1: Type1, . . . ) : ReturnType pre ParameterOk: param1 > . . . post resultOk: result = ....

Expresiones de consulta Una expresin OCL puede ser utilizada para indicar el resultado de una operacin de consulta. Esto se realiza utilizando la siguiente sintaxis:

context Typename:: operationName(parameter1: Type1, . . . ) : ReturnType body: _ alguna expresin


La expresin debe ser conforme con el tipo de la operacin. Al igual que en pre y postcondiciones los parmetros pueden ser utilizados en la expresin. Las precondiciones, postcondiciones y expresiones body pueden ser combinadas luego de especificar el contexto de una operacin. Por ejemplo:

context Person:: getCurrentSpouse() : Person pre: self.isMarried = true body: self.marriage->select (m | m.ended = false ).spouse
Valores iniciales y Derivados Una expresin OCL puede ser utilizada para indicar el valor inicial (o derivado) de un atributo o un extremo de asociacin. Esto se puede realizar utilizando la siguiente sintaxis:

context Typename:: attributeName: Type init: _ alguna expresi_on representando el valor inicial del atributo context Typename:: assocRoleName: Type derive: _ alguna expresin representando la regla de derivacin
La expresin debe ser conforme al tipo resultante del atributo. En el caso que el contexto es un extremo final de asociacin, la expresin debe ser conforme con el tipo en tal extremo final, cuando la multiplicidad es a lo sumo uno; o Set u OrderedSet cuando la multiplicidad es ms de uno. Las expresiones iniciales y de derivacin pueden ser combinadas luego de un contexto. Por ejemplo:

context Person:: income : Integer init: parents.income-> sum() * 1 % derive: if underAge then parents.income->sum() * 1 % else job.salary Endif

Valores y Tipos Bsicos La definicin de OCL incluye un nmero de tipos bsicos predefinidos los cuales estn disponibles para el modelador. Estos tipos de valores bsicos son independientes de cualquier modelo. Los tipos bsicos de OCL son: Boolean, Integer, Real, String.

Tipos Predefinidos: OCL define un nmero de operaciones en los tipos predefinidos. Algunos ejemplos de operaciones en estos tipos son: _ para el tipo Boolean: and, or, xor, not, implies, if-then-else. _ para el tipo Integer: *, +, -, abs(), y otros. _ para el tipo Real: *, +, -, oor(), y otros. _ para el tipo String: size(), substring(), concat(), etc.

Otros tipos bsicos son Collection, Set, OrderedSet, Bag y Sequence, los cuales sern descriptos en las prximas secciones.

Tipos desde el modelo UML


Cada expresin OCL est escrita en el contexto del modelo UML, de un nmero de clasificadores (tipos, clases, etc.), sus caractersticas y asociaciones y sus generalizaciones. Todos los Clasificadores de un modelo UML son tipos que pueden ser utilizados en OCL. Tipos Enumerados Las enumeraciones son tipos de datos (DataTypes en UML) y tienen un nombre. Una enumeracin define un nmero de literales de enumeracin, que son los valores posibles de la enumeracin. OCL puede referir a los valores de una enumeracin. El Datatype Gender de la figura 1 modela los valores female, male. Podemos utilizar la enumeracin de la siguiente forma:

context Person inv: gender = Gender::male


Expresiones Let A veces una subexpresin se utiliza ms de una vez en una restriccin. La expresin Let nos permite definir una variable que puede ser reutilizada en una restriccin para representar una subexpresin. En la siguiente expresin se define una variable llamada

income para representar la funcin self.job.salary->sum(). context Person inv: let income : Integer = self.job.salary-> sum() in if isUnemployed then income < 100 else income >= 100 endif
Una expresin let se puede incluir en cualquier expresin OCL. Y solo es conocida en dicha expresin. Atributos/Operaciones adicionales definidos a partir de expresiones

<<definition>>
Para permitir la reutilizacin de variables (y/o operaciones) en mltiples expresiones OCL es posible definir una expresin definicin (una restriccin definida a partir del estereotipo <<definition>>). Una expresin definicin est asociada a un Classifier y slo puede contener definiciones de atributos (y/o operaciones), nada mas.

La sintxis para una restriccin definicin utiliza la palabra reservada def, como se muestra a continuacin. En la siguiente expresin OCL se define una variable income.

context Person def : income : Integer = self.job.salary-> sum()


La variable income es conocida en el mismo contexto que cualquier propiedad de Persona. Por ejemplo en:

context Person inv: if self.isUnemployee then income < 100 else income >= 100 endif
El nombre de los atributos u operaciones en una expresin let no debe entrar en conflicto con los nombres de los respectivos atributos o extremos de asociacin del clasificador. Tabla 4.1: Regla de Conformidad de Tipos Tipo Set(T1) Sequence(T1) Bag(T1) Integer Conforme a / Es subtipo de Collection(T2) Collection(T2) Collection(T2) Real Condicin si T1 es conforme a T2 si T1 es conforme a T2 si T1 es conforme a T2

Conformidad de Tipos OCL es un lenguaje tipado 2 y los tipos de valores bsicos estn organizados en una jerarqua de tipos. Esta jerarqua determina la conformidad entre diferentes tipos. No es posible, por ejemplo, comparar un entero con un valor booleano o un string. Una expresin OCL en el cual todos los tipos son conformes es una expresin vlida. Una expresin OCL en el cual los tipos no son conformes es una expresin invlida. En este ltimo caso, contendr una error de conformidad de tipo (type conformance error). Un tipo type1 es conforme a un tipo type2 cuando una instancia de type1 puede ser sustituida en cada lugar donde se espera la instancia type2. Las reglas de conformidad para tipos en los diagrama de clases son simples. _ Cada tipo es conforme a su supertipo.

_ La conformidad de tipos es transitiva: si type1 es conforme a type2, y type2 es conforme a type3, entonces type1 es conforme a type3. El efecto de esto es que un tipo es conforme a su supertipo, y a todos sus supertipos (hacia arriba en la jerarqua). La tabla 4.1 muestra algunas reglas de conformidad de tipos: La relacin de conformidad entre los tipos coleccin solo se sostiene si ellos son colecciones de tipos de elementos que se conforman unos a otros. Palabras Reservadas Las palabras reservadas no pueden aparecer en ningn lugar de una expresin OCL como nombre de un package, tipo o propiedad. La lista de palabras reservadas en OCL es: and , attr, context, def, else, endif, endpackage, if, implies, in,

inv, let, not, oper, or, package, post, pre, then, xor.
Comentarios Los comentarios en OCL son escritos luego de dos lneas '--'. Todo lo que est escrito luego de las dos lneas '--', hasta el final de la lnea (incluido el final de lnea) es un comentario.

-- esto es un comentario.
Valores Indefinidos Siempre que una expresin OCL est siendo evaluada, existe la posibilidad de que uno o ms de las consultas sean indefinidas. Si este es el caso, entonces la expresin completa ser indefinida. Hay dos excepciones a esta regla al utilizar operadores lgicos: _ True OR cualquier otra expresin es True. _ False AND cualquier otra expresin es False. _ False IMPLIES cualquier otra expresin es True. _ cualquier otra expresin IMPLIES True es True. Las reglas para OR y AND son vlidas sin importar el orden de los argumentos y son vlidas independientemente si se conoce el valor de las otras subexpresiones. Objetos y Propiedades Las expresiones OCL se pueden referir a tipos, clases, interfaces, asociaciones (actuando como tipos) y tipos de datos. Tambin todos los atributos, extremos de

asociacin, mtodos y operaciones sin efectos laterales que estn definidos en estos tipos pueden ser utilizados. En el modelo de clase, una operacin o mtodo se define como libre de efectos laterales si el atributo isQuery de la operacin es verdadero. En este documento nos referimos a atributos, a extremos de asociacin, a mtodos y a operaciones libre de efectos laterales como propiedades. Por consiguiente, una propiedad es una de las siguientes posibilidades: _ un Atributo, _ un Extremo de una Asociacin (AssociationEnd), _ una Operacin para la cual isQuery es verdadero, _ un Mtodo para el cual isQuery es verdadero. Propiedades El valor de una propiedad de un objeto que es definido en el diagrama de clases es especificado por un punto ('.') seguido del nombre de una propiedad:

context AType inv: self.property


Si self es una referencia a un objeto, entonces self.property es el valor de propiedad property en self. Propiedades: Atributos Ejemplo: La edad de una persona es escrita como

context Person inv: self.age . . .


El valor de esta expresin es el valor del atributo age de la Persona self. El tipo de esta expresin es el tipo del atributo age, el cual en este caso es un tipo Integer bsico. Es posible expresar clculos o comparaciones a partir de los atributos y operaciones definidas en los tipos de valores bsicos. Por ejemplo, una regla de negocios podr ser 'la edad de una persona es siempre mayor o igual a 18'.

context Person inv: self.age >= 18

Propiedades: Operaciones Las operaciones pueden tener parmetros. Por ejemplo, en el diagrama de la figura 1, un objeto Persona tiene un salario expresado como funcin de una fecha. Esta operacin ser accedida como se muestra a continuacin, para una Persona

aPerson y una fecha aDate: aPerson.income(aDate)


El resultado de esta operacin es el valor del tipo retornado de la operacin, que es Integer en este ejemplo. Si la operacin tiene parmetros de salida (out) o entrada/ salida (in/out), el resultado de esta operacin es una tupla conteniendo todos los parmetros out, in/out y el valor retornado. Por ejemplo, si la operacin

income tuviera un parmetro out denominado bonus, el resultado de la operacin es


el tipo Tuple(bonus: Integer, result: Integer). Es posible acceder a estos valores utilizando los nombres de los parmetros out, y la palabra reservada result, por ejemplo:

aPerson.income(aDate).bonus = 300 aPerson.income(aDate).result = 500


Note que los parmetros out no necesitan ser incluidos al invocar la operacin. Solo son necesarios los parmetros in o in/out.

Definiendo Operaciones La operacin en si misma podr ser definida por una restriccin postcondicin. Es posible referirnos al objeto que es retornado por la operacin a partir de la palabra reservada result, de la siguiente forma:

context Person:: income(d: Date) : Integer post : result = self.age * 1000


En el lado derecho de esta definicin podemos referirnos a la operacin que esta siendo definida (es decir, la definicin puede ser recursiva). Adems en una pre o postcondicin es posible utilizar los parmetros de la operacin. El tipo result, cuando la operaci_on no tiene par_ametros out o in/out, es el tipo retornado de la

operacin. Cuando la operacin tiene parmetros out o in/out, el tipo retornado es una Tupla como se explic anteriormente. La postcondicin para la operacin

income con un parmetro out denominado bonus podr tomar la siguiente forma: context Person:: income(d: Date, bonus:Integer) : Integer post : result = Tuple (bonus = ....., result = ......)
Para referirnos a una operacin o mtodo que no tiene parmetros, es obligatorio escribir parntesis con una lista vaca de argumentos:

context Company inv: self.stockPrice() > 0


Propiedades: Extremos de Asociacin y Navegacin Comenzando desde un objeto especfico, es posible navegar una asociacin en el diagrama de clases para hacer referencia a otros objetos y sus propiedades. De esta forma, se navega la asociacin utilizando el extremo opuesto de una asociacin:

object.rolename
El valor de esta expresin es el conjunto de objetos del otro lado de la asociacin cuyo nombre de rol es rolename. Si la multiplicidad del extremo de la asociacin tiene un mximo de uno ('0..1' _o '1'), entonces el valor de esta expresin es un objeto. En el contexto de Compaa del diagrama de la figura 1, es posible escribir:

context Company inv: self.manager.isUmployed = false inv: self.employee-> notEmpty()


La evaluacin de la primera expresin resultar en un objeto de tipo Persona, debido a que la multiplicidad de la asociacin es uno. La evaluacin de la segunda expresin resultar en un conjunto de personas. Por defecto, las navegaciones resultarn en Conjuntos. Las colecciones, como Sets, Bags, Sequences, son tipos predefinidos en OCL. Ellos tienen un gran nmero de operaciones predefinidas. Una propiedad de una coleccin en

si misma puede ser accedida usando la notacin echa ('->') seguida del nombre de la propiedad. En el contexto de Persona es posible definir:

context Person inv: self.employer-> size() < 3


En el ejemplo se aplica la propiedad size() en el conjunto self.employer, el cual resultar en el nmero de empleadores de la Persona self.

context Person inv: self.employer-> isEmpty() isEmpty() en el conjunto

En

este

ltimo

ejemplo

se

aplica

la

propiedad

self.employer.
Este se evala a verdadero si el conjunto de empleadores es vaco, de otra manera es falso. Usando Pathnames para Paquetes y Propiedades En UML, los tipos estn organizados en paquetes. OCL provee una manera flexible de referenciar explcitamente a los tipos de otros paquetes usando un prefijo 'package::pathname'. La sintxis es un nombre de un paquete, seguido de dos 'dos puntos'.

Packagename::Typename
El uso de pathnames es transitivo y puede ser usado para paquetes dentro de paquetes.

Packagename1::Packagename2::Typename
Acceso a propiedades de supertipos que han sido sobrescritas Siempre que las propiedades estn redefinidas dentro de un tipo, las propiedades de los supertipos pueden accederse utilizando la operacin oclAsType(). Siempre que tengamos una clase B, como un subtipo de una clase A, y una propiedad p1 de A y de B, es posible escribir:

context B inv: self.oclAsType(A).p1 -- accedemos a la propiedad p1 definida en A self.p1 -- accedemos a la propiedad p1 definida en B

Caractersticas de Tipos. Todas las propiedades mencionadas hasta ahora son propiedades de las instancias de las clases. Los tipos son predefinidos o son definidos en el modelo de clases. En OCL, tambin es posible usar caractersticas definidas en tipos/clases. Estas, por ejemplo, son caractersticas de alcance de clases definidas en el modelo de clase. Adems, diversas caractersticas estn predefinidas en cada tipo. Una caracterstica predefinida en clases, interfaces y enumeraciones es allInstances, la cual resulta en el conjunto de todas las instancias del tipo en el momento especfico cuando la expresin es evaluada. Para verificar que cada persona tiene un nombre nico, se podr escribir la siguiente expresin:

context Person inv: Person.allInstances() -> forAll(c1, c2 | c1 <> c2 implies c1.name <> c2.name ) Person.allInstances() representa el conjunto de todas las personas y es de tipo Set(Person).
Colecciones. Los tipos coleccin juegan un importante rol en expresiones OCL al igual que en todo lenguaje orientado a objetos. Una nica navegacin de una asociacin resulta en un conjunto, navegaciones combinadas en un Bag, y navegaciones sobre asociaciones adornadas con {ordered} resultan en OrderedSet. El tipo Coleccin (Collection) est predefinido en OCL. El tipo Coleccin define un gran nmero de operaciones predefinidas que permiten que el autor de una expresin OCL (el modelador) manipule colecciones. Para ser consistente con la definicin de OCL como un lenguaje de expresin, las operaciones de coleccin nunca cambian las colecciones; es decir isQuery es siempre verdadero. Aunque las operaciones pueden resultar en una coleccin, en lugar de modificar la coleccin original proyectan el resultado en una nueva coleccin. La clase que representa las colecciones, Collection, es un tipo abstracto, con tipos de coleccin concretos como subtipos. OCL distingue cuatro tipos de colecciones:

_Set Es un conjunto, i.e. no contiene elementos duplicados.

_OrderedSet Es un conjunto en el cual sus elementos estn ordenado. _Bag Es similar a un conjunto pero puede contener duplicados. _Sequence Es similar a Bag, y sus elementos est_an ordenados.
Literales de Colecciones Las colecciones Sets, Sequences, y Bags pueden ser especificadas a partir de literales en OCL. Los elementos de una coleccin estn separados por comas y rodeados por llaves. El tipo de la coleccin se escribe antes de las llaves. Se definen a continuacin ejemplos de colecciones.

Set { 1, 2, 3} Set { 'manzana', 'naranja', 'frutilla'} Sequence {1, 2, 2, 3, 3, 3} Sequence {'manzana', 'naranja'} Bag {1, 3, 4, 3, 5, 3}
Es posible crear una secuencia de enteros consecutivos a partir de la especificacin de un intervalo, dicho intervalo se escribe entre llaves: los extremos del mismo consisten de dos expresiones de tipo entero, Int-expr1 e Int-expr2, separados por '..'. Esto denota a todos los enteros entre estos valores, inclusive los extremos del intervalo. Las siguientes dos secuencias

Sequence { 1..7 } Sequence { 1..(4 + 7) }


son equivalentes a la siguiente

Sequence {1, 2, 3, 4, 5, 6, 7 }
Las diferentes formas a partir de las cuales es posible obtener un Set, OrderedSet,

Sequence o Bag son:


_ por medio de un literal, ver ejemplo 4.5.8, _ una navegacin comenzando desde un nico objeto el cual puede resultar en una coleccin.

context Person inv: self.employer


_ operaciones de colecciones pueden resultar en nuevas colecciones.

collection1 -> union(collection2)

Colecciones de Colecciones. Los elementos de una coleccin pueden ser colecciones. Jerarqua de Tipos y Reglas de Conformidad de Tipos. Adems de las reglas de tipo de conformidad se sostienen las siguientes reglas para todos los tipos incluyendo los tipos coleccin: Definicin: Los tipos Set(X), Bag(X) y Sequence(X) son todos subtipos de Collection(X). Las reglas de conformidad de tipo para los tipos Collection son: _ Type1 es conforme a Type2 cuando ellos son idnticos (de acuerdo a reglas estndar para todos los tipos). _ Type1 es conforme a Type2 cuando es un subtipo de Type2 (de acuerdo a reglas estndar para todos los tipos). _ Collection(Type1) es conforme a Collection(Type2), cuando Type1 es conforme a Type2. Esto es tambin valido para Set(Type1)/Set(Type2), Sequence(Type1) /Sequence(Type2), Bag(Type1)/Bag(Type2). _ La conformidad de tipo es transitiva: Si Type1 es conforme a Type2, y Type2 es conforme a Type3, luego Type1 es conforme a Type3 (de acuerdo a reglas estndar para todos los tipos). Ejemplo: Si Bicycle y Car son dos subtipos de Transport: Set(Bicycle) es conforme a Set(Transport) Set(Bicycle) es conforme a Collection(Bicycle) Set(Bicycle) es conforme a Collection(Trasport) Set(Bicycle) no es conforme a Bag(Bicycle) Valores Previos en PostCondiciones. OCL puede ser utilizado para especificar pre- y post- condiciones en operaciones y mtodos en UML. En una precondicin, la expresin puede referir a dos conjuntos de valores para cada propiedad de un objeto: _ El valor de una propiedad al comienzo de la operacin _o mtodo. _ El valor de una propiedad luego de que la operacin _o mtodo se ha ejecutado. El valor de una propiedad en una postcondicin es el valor de la propiedad una vez completada la operacin. Para referir al valor de una propiedad al comienzo de la operacin, es posible escribir el nombre de la propiedad junto al postfijo @pre.

De acuerdo a la siguiente expresin:

context Person:: birthdayHappens() post: age = age@pre + 1


La propiedad age@pre se refiere al valor de la propiedad age de Persona al comienzo de la operacin. Si la propiedad tiene parmetros, el postfijo @pre se escribe luego de la propiedad y antes de los parmetros. De acuerdo a la siguiente expresin:

context Company:: hireEmployee(p: Person) post: employees = employees@pre -> including(p) and stockprice() = stockprice@pre() + 10
La operacin mostrada anteriormente tambin podra especificarse a partir de una precondicin y una postcondicin.

context Company:: hireEmployee(p: Person) pre: not employees-> includes(p) post: employees -> includes(p) and stockprice() = stockprice@pre() + 10
Cuando se toma el valor previo de una propiedad _este se evala a un objeto, todas las propiedades que son accedidas por este objeto son los nuevos valores (una vez completada la operacin) de _este objeto. La siguiente expresin

a.b@pre.c
toma el viejo valor de la propiedad b de a, llamemos x, y luego el nuevo valor de c de x.

a.b@pre.c@pre
toma el viejo valor de la propiedad b de a, llamemos x, y luego el viejo valor de c de x. El postfijo @pre slo se permite en expresiones OCL que son parte de una Postcondicin. Por otro lado, preguntar sobre la propiedad corriente de un objeto que ha sido destruido durante la ejecucin de una operacin resultar en indefinido (undefined); como as tambin, referir a un valor previo de un objeto que ha sido creado durante la ejecucin de la operacin resulta en indefinido.

Integracin de OCL en artefactos modelados con UML

Construyendo modelos con OCL Este captulo describe como un modelo UML puede complementarse con expresiones OCL resultando en un modelo que es lo suficientemente completo y coherente. Cuando comenzamos un modelo nuevo, el primer paso es construir un nmero de diagramas. El diagrama ms importante en el modelo es el diagrama de clases. Debido a que cualquier modelo est estructurado alrededor de clases y componentes, es en ellos donde se enfoca la mayor parte de la informacin. OCL confa en los clasificadores definidos en un diagrama de clase UML. Por lo tanto, este diagrama deber construirse primero. Luego, es posible construir otros diagramas de acuerdo a la necesidad de precisin en la especificacin del sistema. Completando Diagramas de Clase El modelo dibujado en un diagrama de clase puede aumentarse con informacin extra en numerosos lugares, por ejemplo: Reglas de derivacin: El valor de un elemento derivado (atributo o extremo de asociacin) puede especificarse a partir de otros valores en modelo. Esto es posible definiendo una expresin del tipo regla de derivacin (expresiones que utilizan la etiqueta derive). Valores Iniciales: El valor inicial de un atributo o extremo de asociacin puede especificarse a partir de una expresin OCL. Estas expresiones utilizan la etiqueta init. Cuerpo de Operaciones de Consulta Un diagrama de clase puede introducir un nmero de operaciones de consulta. Se utiliza para ello una expresin body.

OCL es un lenguaje de consulta completo, semejante a SQL.


Invariantes: Es posible definir condiciones booleanas que deben ser alcanzadas por todas las instancias de un clasificador. Esto es posible a partir de expresiones OCL invariantes (etiqueta inv). Pre y Postcondiciones Es posible definir expresiones booleanas que deben ser verdaderas en el momento que la operacin comienza su ejecucin o finaliza su ejecucin. Estas expresiones utilizan la etiqueta pre and post. Mensajes en Postcondiciones: Un aspecto de postcondiciones que es muy til para definir interfaces es el hecho que una postcondicin puede establecer que una determinada operacin ha sido invocada. Las postcondiciones contienen informacin de

mensajes cuando existe necesidad de especificar aspectos dinmicos de un elemento del modelo sin revelar la implementacin actual. Ciclos en Modelos de Clase Muchos modelos de clase reflejan ciclos en el sentido que uno puede comenzar navegando a partir de una instancia a travs de varias asociaciones, y retornar a una instancia de la misma clase. En el diagrama de clases, esto se muestra como un ciclo de clases y asociaciones. Muchas veces, estos ciclos son motivo de ambigedades. En el ejemplo de la figura 2 se muestra un diagrama de clase con un ciclo. En este modelo una persona (Person) es duea de una casa (House), la cual se paga a partir de una hipoteca (Mortgage). La hipoteca toma como prenda de seguridad la casa (House) de la cual es dueo la persona (Person). El modelo aunque parece ser correcto es impreciso. El modelo permite que una persona tenga una hipoteca que tome como prenda de seguridad una casa de la cual es duea otra persona. Esto, claramente no es la intensin del modelo. Podemos establecer fcilmente el invariante que necesitamos a partir de la siguiente expresin:

context Person inv: self.mortgages.security.owner->forAll(owner: Person | owner = self)

Figura 2

Multiplicidad Dinmica Las asociaciones en un diagrama de clases pueden constituir especificaciones imprecisas del sistema. Este es el caso cuando la multiplicidad de una asociacin no es fija pero se deber determinar a partir de otro valor en el sistema. Esto se denomina multiplicidad dinmica.

Multiplicidad Opcional Una multiplicidad opcional de una asociacin en un diagrama de clases es a veces una especificacin parcial de lo que realmente se pretende modelar. A veces la opcionalidad es libre; esto es, en algunas circunstancias puede haber uno o ningn objeto asociado. Muchas veces, una asociacin opcional no es realmente libre. Si un objeto asociado puede (o debe) estar presente depende del estado de los objetos involucrados. Por ejemplo en la figura 2 la asociacin opcional no es completamente libre. Si una persona tiene un prstamo, el o ella debe tener una casa. Esta restriccin puede ser especificada por el siguiente invariante:

context Person inv optionality: mortgages->notEmpty() implies houses->notEmpty()


En general, cuando una multiplicidad opcional est presente en un diagrama de clase, es posible utilizar un invariante OCL para describir precisamente las circunstancias bajo las cuales la asociacin opcional puede ser vaca o no. Restricciones Or El diagrama de clase puede contener una restriccin or entre dos asociaciones, como se muestra en la figura 3. Esta restriccin significa que una de las potenciales asociaciones puede ser instanciada a la vez por un nico objeto. Esto se muestra como una lnea punteada conectando dos o mas asociaciones (las cuales deben tener al menos una clase en comn). La lnea punteada es etiquetada con {or}. La multiplicidad de las asociaciones debe ser opcional; de otro modo, ellas no podrn ser vacas. Note que la representacin visual de una restriccin or es ambigua en ciertas situaciones. Este es el caso cuando dos asociaciones entre las mismas dos clases tienen multiplicidad opcional en ambos extremos de ambas asociaciones. La restriccin or visual puede ser leda en dos direcciones. En una direccin, esta puede significar que una persona tiene un managedProject o un performedProject, pero no ambos. En otra direccin, esto puede significar que el proyecto tiene un projectLeader o un projectMember, pero no ambos. Por consiguiente, son posibles dos interpretaciones diferentes. Aunque la eleccin de la interpretacin parece obvia en este caso, es posible imaginar las consecuencias si alguien hace una interpretacin diferente. Al especificar una restriccin visual or con una restriccin OCL se resuelve el problema de ambigedad. Por ejemplo para resolver la primer ambigedad, se deber aumentar el diagrama con el siguiente invariante:

context Person inv: managedProject->isEmpty() or performedProject->isEmpty() El invariante que de_ne la segunda interpretaci_on es: context Project inv: projectLeader->isEmpty() or projectMember>isEmpty()

Figura 3 Este ejemplo muestra la importancia de la especificacin de restricciones e ilustra como asegurar que un modelo no sea ambiguo. Completando Diagramas de Componentes Las expresiones OCL no se utilizan mucho en diagramas de componentes (component or deployment diagrams). Solamente se pueden utilizar expresiones OCL cuando los elementos que se dibujan en un diagrama de clase estn presentes en un diagrama de componente. Por ejemplo, cuando un diagrama de componente contiene especificacin explicita de sus interfaces, las operaciones en las interfaces pueden especificarse a partir de pre y postcondiciones.

Completando diagramas de Interaccin Las expresiones OCL se pueden utilizar para completar diagramas UML de interaccin. El ejemplo de esta seccin utiliza el diagrama mostrado en la figura 3. En el sistema R&L, las nuevas transacciones se introducen a travs de una operacin de LoyaltyProgram llamada addTransaction. Esta operacin tiene cinco parmetros: 1. El nmero de la cuenta para la cual se realiza la transaccin, llamada accNr de tipo Integer.

2. El nombre del socio del programa que ofrece el servicio para el cual se realiz la transaccin, llamada pName de tipo String. 3. La identificacin del servicio, llamado servId de tipo Integer. 4. La cantidad pagada por el servicio, llamado amnt de tipo Real. 5. La fecha en la cual la transaccin tomo lugar, llamado d de tipo Date. La operacin addTransaction implementa el siguiente algoritmo. Primero, se selecciona el servicio correcto. Este servicio calcula los puntos ganados y gastados por la transaccin y crea un objeto transaccin del tipo correcto. El objeto es agregado a la asociacin del servicio que se denomina transactions. Luego, la cantidad correcta es seleccionada. La nueva transaccin creada es agregada a las transacciones asociadas con esta cuenta, mientras se ajusta el balance de la cuenta. Finalmente, la tarjeta correcta se selecciona y la nueva transaccin es agregada a las transacciones asociadas con esta tarjeta. Como un ejemplo elaborado de una postcondicin OCL, la operacin addTransaction es especificada de la siguiente forma:

context LoyaltyProgram::addTransaction( accNr: Integer, pName: String, servId: Integer, amnt: Real, d: Date = post: let acc: LoyaltyAccount = Membership.account->select(a | a.number = accNr ), newT: Transaction = partners-> select (p | p.name = pName) .deliveredServices->select( s | s.serviceNr = servId) .transactions->select( date = d and amount = servId), card: CustomerCard = Membership->select(m | m.account.number = accNr).card in acc.points = acc.points @pre + newT.points and
CONSTRUYENDO MODELOS CON OCL

newT.oclIsNew() and amnt = 0 implies newT.oclIsTypeOf( Burning ) and amnt > 0 implies newT.oclIsTypeOf( Earning ) and acc.transactions - acc.transactions @pre = Setf newT g and card.transactions - card.transactions @pre = Setf newT g

Instancias En un diagrama de interaccin, se muestran instancias. Debido a nuestro

requerimiento, de que un modelo debe ser internamente consistente, cada instancia mostrada debe ser de un tipo declarado en algn diagrama de clase. Mayor an, el destinatario de un mensaje en un diagrama de interaccin debe ser conocido y visible por el emisor del mensaje, aunque para esta afirmacin no hay una regla en UML que lo establezca explcitamente. En el diagrama se puede indicar el nombre por el cual el emisor conoce al destinatario. Esto facilita la lectura de la expresin. Otra manera de expresar esto es utilizar nombres para las instancias, y acompaar el diagrama con expresiones OCL que establezcan la relacin entre las instancias. En la figura 3 es posible notar que la instancia de LoyaltyAccount se denomina m.account, donde m referencia a la instancia Membership en el diagrama. Para establecer la relacin entre las otras instancias en el diagrama, podemos utilizar la siguiente expresin:

lp.partners->includes(pp) and pp.name = pName pp.deliveredServices->includes(s) and s.serviceNr = servId lp.Membership->includes( m ) and m.account.number = accNr

Figura 4 Condiciones Una parte de las interacciones en un diagrama de secuencia o colaboracin puede tener una condicin que especifica en que circunstancias esa parte se ejecuta. Esta condicin se puede escribir como una expresin OCL. Debido a que un diagrama de interaccin es un diagrama de instancia, la expresin OCL esta escrita en el contexto de una instancia, no de un tipo. Esto es raro; por consiguiente, se requiere atencin especial para determinar el tipo contextual y la instancia contextual. La instancia contextual es la instancia para cuya lnea de vida se escribe la condicin, y el tipo contextual es el tipo de la instancia.

Figura 5 Se muestra un ejemplo en la figura 5, el cual extiende el diagrama de secuencia de la figura 4. El objeto servicio s crea una transaccin del tipo adecuado, dependiendo del parmetro de la operacin addTransaction. Estas condiciones estn escritas como expresiones OCL vlidas, dado el hecho que los diagramas especifican las operaciones y sus parmetros pueden ser utilizados. Valores de los parmetros actuales Es posible utilizar una expresin OCL para especificar los valores actuales de un parmetro de un mensaje. Un mensaje a un objeto en un diagrama de interaccin debe ser conforme con la operacin en el tipo del objeto destinatario del mensaje. Que sea conforme significa que el nombre de la operacin es la misma, y los parmetros en el mensaje son del tipo indicado por los parmetros de la operacin. De igual forma, el resultado del mensaje en un diagrama de interaccin (mostrado por una lnea punteada en el diagrama de secuencia, o una asignacin en el diagrama de interaccin) debe ser del tipo indicado, al igual que el tipo resultante de la invocacin de la operacin.

Completando Diagramas de Estados (State-Charts) Las expresiones OCL pueden utilizarse de diversas formas en los diagramas de estados de UML. En todos los casos, el tipo contextual es la clase a la cual pertenece el diagrama de estados, y la instancia contextual es la instancia para la cual una transicin en el diagrama de estados se dispara. Utilizaremos en esta seccin un ejemplo de un sistema simple de control de procesos para ejemplificar como utilizar expresiones OCL con diagramas de estados.

Ejemplo de un diagrama de Control de Procesos simple. En esta seccin se muestra un ejemplo de un sistema simple de control de procesos de una fbrica que produce botellas con una cierta cantidad de lquido. Las clases del sistema estn dibujadas en la figura 6. El proceso es el siguiente: Un objeto lnea toma un objeto botella desde el stock, y dispara un objeto filler para llenar una botella. La botella monitorea su contenido y enva un mensaje al filler cuando est llena. El filler luego avisa a la lnea para mover la botella al sistema que tapa la botella (capper). Guardas Una expresin OCL puede ser utilizada para expresar guardas en un diagrama de estados. Un guarda es una condicin en la transicin en un diagrama de estados. El guarda generalmente se incluye en el diagrama de estados en s mismo. En este caso se escribe entre corchetes ([ y ]) luego del evento que dispara la transicin. La figura 6 incluye un guarda en la transicin desde el estado stopped al estado filling. En este caso, el objeto Filler cambia de estado slo si contiene suficiente lquido. Acciones Una accin en un diagrama de estados representa un llamado a una operacin o el envo de un evento. Las acciones pueden estar acopladas a transiciones o estados en un diagrama de estados. Cuando estn acopladas a una transicin, la accin es ejecutada si la transicin se dispara, en el objeto o conjunto de objetos especfico(s) comnmente denominados el objetivo o target. Cuando est acoplada a un estado, la accin se ejecuta cuando el objeto asume este estado, cuando el objeto deja este estado o cuando un evento ocurre. En el ltimo caso, el target es el objeto self. Una expresin OCL puede utilizarse para identificar el target de una accin, ya sea acoplada a una transicin o a un estado. Por ejemplo, la accin theline.move(b) en la figura 6 tiene como target el objeto Line vinculado a la instancia contextual de Filler, y la accin myFiller.stop() de la figura 7 tiene como target el objeto Filler vinculado a la instancia contextual de Bottle. Valores de Parmetros actuales Debido a que las acciones representan llamadas a operaciones o el envo de eventos, y ambos pueden tener parmetros, las acciones en los diagramas de estados pueden tener parmetros.

Figura 6

Figura7 As como los parmetros en mensajes de un diagrama de interaccin, estos son valores actuales, y no los parmetros formales de las correspondientes operaciones o eventos enviados. Se puede especificar el valor de tales parmetros haciendo uso de una expresin OCL, en cuyo caso el contexto de la expresin es la transicin o estado al

cual se acopla la accin. En la figura 5, dos acciones tienen un valor actual como parmetro. Evento de cambio Un evento de cambio es un evento que se genera cuando uno o mas atributos o asociaciones cambian el valor. El evento ocurre siempre que el valor indicado por la expresin cambia de falso a verdadero. Un evento de cambio est dotado de la palabra reservada when, parametrizado con una expresin OCL. Por ejemplo, en el diagrama de transicin de estados de la clase Bottle de la figura 6, un evento de cambio est asociado a la transicin que se encuentra entre el estado partiallyFilled y el estado

full. La transicin toma lugar cuando la condicin contents = capacity sea


verdadera. No se necesita ningn evento generado externamente. Note que el evento de cambio es diferente de la condicin de guarda. Una condicin de guarda se evala una vez que el evento se dispara. Si el guarda es falso, la transicin no ocurre, y cuando ninguna otra transicin para el mismo evento es especificada, el evento se pierde. Cuando un evento de cambio ocurre, un guarda puede an bloquear cualquier transicin que de otro modo estar disparada por tal cambio. Restricciones en Estados Usualmente, estas son restricciones en valores de vnculos y atributos cuando un objeto est en un determinado estado. Estos debern ser especificados explcitamente. Por ejemplo, para la clase Bottle, las siguientes condiciones invariantes debern sostenerse:

context Bottle inv: (self.oclInState(capped) or self.oclInState(full) ) implies contents = capacity inv: self.oclInState(empty) implies contents = 0 inv: self.oclInState(capped) implies myCap-> notEmpty() inv: self.oclInState(partiallyFilled) implied myFiller->notEmpty()

Figura 8 Claves para la especificacin de expresiones OCL Esta seccin provee algunas claves importantes acerca de como escribir expresiones OCL mas claras. Evitar expresiones de navegacin complejas Al utilizar OCL, es posible escribir expresiones complejas y largas en las que se navegue a travs del modelo de objetos completo. Incluso alguien podr escribir todos los invariantes en un modelo de clase comenzando desde un solo contexto, pero esto no ser una buena prctica. Cualquier navegacin que atraviesa el modelo de clase crea acoplamiento entre los objetos involucrados. Un aspecto esencial de la orientacin a objetos es la encapsulacin. Al utilizar navegaciones largas hace que los detalles de objetos distantes sean conocidos por el objeto desde el cual comienza la navegacin. Si es posible, es recomendable limitar el conocimiento del objeto a su entorno directo, que son las propiedades de su tipo. Otra desventaja de las expresiones con navegaciones complejas es que las escritura, la lectura y el comprensin de invariantes se torna muy difcil. Elegir adecuadamente el contexto Por definicin, los invariantes se aplican a un tipo, por lo tanto, es importante especificar el invariante en el tipo correcto. No hay reglas estrictas que puedan ser aplicadas en todas las circunstancias, pero las siguientes recomendaciones pueden ser tiles en el momento de seleccionar el contexto de una expresin: 1) si el invariante restringe el valor de un atributo de una clase, la clase que contiene el atributo es un candidato clave.

2) Si el invariante restringe los valores de atributos de mas de una clase, las clases que contienen cualquiera de los atributos restringidos son candidatos claves. 3) si se determina que una clase tiene la responsabilidad de mantener la restriccin, esta clase deber ser el contexto. 4) Cualquier invariante deber navegar el nmero mas pequeo posible de asociaciones. A veces es una buena prctica describir el mismo invariante utilizando diferentes clases como contexto. La restriccin que sea la mas fcil de leer y escribir es la mas adecuada para representar el contexto de la restriccin. Dividir restricciones and Las restricciones son especificadas durante el modelamiento, y ellas debern ser fciles de leer y de escribir. Generalmente la tendencia es escribir largas restricciones. Por ejemplo, todas las restricciones invariantes de una clase pueden ser expresadas en un invariante lo suficientemente largo, o todas las precondiciones de una operacin podrn ser escritas en una nica restriccin. En general, es recomendable partir una restriccin complicada en diversas restricciones separadas. Por ejemplo, el siguiente invariante para la clase

ProgramPartner: context LoyaltyProgram inv: partners.deliveredServices->forAll(pointsEarned = 0) and Membership.card->forAll(goodThru = Date.fromYMD(2000,1,1) ) and participants->forAll( age() > 55)
Este invariante es completamente vlido y til, pero es posible reescribirlo como tres invariantes separados, de tal forma que sea mas fcil de leer:

context LoyaltyProgram inv: partners.deliveredServices->forAll(pointsEarned = 0) inv: Membership.card->forAll(goodThru = Date.fromYMD(2000,1,1) ) inv: participants->forAll( age() > 55)
Algunas ventajas de dividir invariantes son: 1) Cada invariante se torna menos complejo y por consiguiente mas fcil de leer y escribir.

2) Al determinar si un invariante es apropiado, la discusin se puede enfocar precisamente en aquel invariante que corresponda, en lugar de considerar el invariante completo (el inicial) como un todo. 3) Es mas fcil verificar y buscar porque un invariante falla. En general, cuanto mas simple sea el invariante, el problema es mas fcil de localizar. 4) Estas mismas consideraciones son vlidas para precondiciones. Nombrar siempre los extremos de asociacin En el caso de asociaciones mltiples entre las mismas clases, es obligatorio nombrar las asociaciones. Sin embargo, an cuando no sea obligatorio, es una buena prctica nombrar las asociaciones. Solo es admisible omitir el nombre de asociaciones no navegables. El nombre del extremo de asociacin, como el nombre de un atributo, indica el propsito de tal elemento para el objeto que contiene dicha asociacin. Adems, nombrar los extremos de asociacin es til durante la implementacin, debido a que el mejor nombre para el atributo (o miembro de clase) que representar la asociacin ya estar determinado. Comentarios En este captulo hemos ejemplificado como los diagramas UML mas importantes se pueden complementar con expresiones OCL y de esta forma construir modelos UML/OCL precisos. El diagrama de clase puede beneficiarse de las expresiones OCL estableciendo reglas de derivacin, valores iniciales, el cuerpo de operaciones de consulta, invariantes, precondiciones y postcondiciones. Las expresiones OCL tambin pueden ser tiles para especificar ciclos, especificar multiplicidad dinmica u opcional, etc. En un diagrama de componentes, se pueden utilizar las expresiones OCL para especificar explcitamente las interfaces y clases mencionadas en el diagrama. El diagrama de interaccin puede ser mejorado especificando las instancias, los valores de parmetros actuales, y estableciendo condiciones. El diagrama de estados puede aumentarse con guardas, targets explcitos de acciones, y valores de parmetros actuales. Los eventos de cambios y restricciones en estados tambin pueden ser expresados utilizando OCL. Hemos mencionado tambin algunas clases a tener en cuenta para especificar expresiones de una forma mas adecuada.

También podría gustarte