Documentos de Académico
Documentos de Profesional
Documentos de Cultura
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
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:
FIGURA 1:
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:
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
pre:
post:
antes
de
las
precondiciones
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 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.
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 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:
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
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:
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:
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:
si misma puede ser accedida usando la notacin echa ('->') seguida del nombre de la propiedad. En el contexto de Persona es posible definir:
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:
_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, 2, 3, 4, 5, 6, 7 }
Las diferentes formas a partir de las cuales es posible obtener un Set, OrderedSet,
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.
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.
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.
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:
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: 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
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
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.