Sei sulla pagina 1di 23

Ingeniera de Software I

El lenguaje de especificacin OCL


2 cuatrimestre 2005

Limitaciones del diagrama de clases


Es sabido que dentro de la metodologa UML el diagrama de clases es una poderosa herramienta de modelizacin de la naturaleza propia de la informacin. En este diagrama se estructura la informacin especificando la naturaleza central de los tipos de objetos referidos (clases) con sus referencias inter-clases (asociaciones, clases de asociacin junto con sus correspondientes multiplicidades), adems de las relaciones jerrquicas entre clases (herencia, especializacin, generalizacin). El objetivo del uso de esta herramienta es establecer una abstraccin respecto a todos los casos particulares posibles, ofreciendo un marco sintctico para definir la realidad del modelo, separando aquellos casos particulares correctos (los contemplados dentro del diagrama de clases, que es una abstraccin de todos ellos), de los que no. A esta separacin que provee el diagrama entre los casos particulares correctos y los incorrectos, lo vamos a llamar el invariante inherente al diagrama, que representa las restricciones propias que debe cumplir el modelo. Sin embargo, estas restricciones provistas por el diagrama terminan siendo puramente sintcticas. Pero seguramente existen otro tipo de restricciones que pueden presentarse, que son condiciones que se deben aplicar a los objetos representados, y que se deben cumplir. Estas restricciones son realmente semnticas (de significado), y se diferencian de las inherentes al diagrama, que son puramente sintcticas. Para poder expresar estar restricciones semnticas debemos poder expresar las condiciones propias de estas restricciones semnticas, que no pueden ser representadas con el diagrama de clases. Para esto es necesario poseer un lenguaje para poder escribir estas condiciones. Para ello, dentro del contexto de UML y asociado al diagrama de clases, deberan estar anexadas las condiciones escritas en un lenguaje que expresen todas aquellas restricciones semnticas y otras caractersticas que no se pueden reflejar en el diagrama y que se pueden reflejar con este mismo lenguaje.

OCL (Object Constraint Language)


El lenguaje de especificin OCL aparece en el documento Semntica de UML como lenguaje propuesto para especificar las restricciones semnticas del diagrama de clases, junto a otro tipo de definiciones. OCL se puede utilizar en cualquier contexto en que se use el diagrama de clases al que est asociado (como por ejemplo, en el modelo conceptual o en el diseo). OCL es un lenguaje hbrido orientado a objetos-funcional, y es tipificado, porque usa el concepto de tipos de datos. Estos tipos de datos se encuentran jerarquizados a travs de relaciones de inclusin. Tambin existen varios tipos bsicos predefinidos (similares a los de cualquier lenguaje), y unos pocos tipos paramtricos (o estructurados) predefinidos. Los tipos no predefinidos van a estar asociados a las clases del diagrama de clases. El componente central construdo por este lenguaje es la expresin, que se manipula a travs de operaciones que garantizan la transparencia referencial y la falta de efectos colaterales. Estas son caractersticas compartidas con los lenguajes funcionales, que son declarativos. Toda expresin vlida para el lenguaje OCL debe tener asociado un tipo de datos. Las expresiones se pueden mapear fcilmente al concepto de objetos, ya que cada

tipo bsico no predefinido se puede vincular a una clase del diagrama, y algunas de las operaciones de un tipo bsico no predefinido se modelan como atributos y mtodos/responsabilidades de la clase original. Las asociaciones entre clases tambin se modelan en OCL usando los roles de ambas clases participantes en la asociacin, que deben estar rotulados (en ambos extremos). El rol de una clase en una asociacin con una segunda clase, expresa que ese rol es un pseudoatributo del tipo de dato vinculado a esa segunda clase. Todos estos componentes asociados a las clases, tambin se ven reflejados en los tipos de OCL. Las expresiones del lenguaje OCL se estructuran hasta llegar a su punto ms alto, que es el de formar parte de una definicin. En cada definicin de OCL se describe cada restriccin semntica del diagrama de clases, junto a otras propiedades tambin descriptas con expresiones. Cada definicin en OCL se aplica a lo que se llama un contexto, que representa el destinatario del diagrama de clases sobre quien se aplica esa definicin. Entre estos contextos se encuentran: - Una clase (se aplica a todas expresiones-objetos cuyo tipo de datos asociado es el vinculado a esta clase). - Un mtodo/responsabilidad de una clase. - Un atributo derivado de una clase. - Un mtodo/responsabilidad derivado (tambin llamado query) de una clase.

Tipos de definiciones
1) Invariantes context idclase inv: [[Descripcin del invariante]] expBool Representa una condicin (restriccin semntica) que deben cumplir todas las expresiones-objetos pertenecientes al tipo de datos vinculados a la clase idclase. La condicin a cumplirse se expresa en la expresin expBool que es de tipo Boolean (lgico). La expresin booleana debe evaluar en verdadero si se aplica a expresiones-objetos perteneciente al tipo de la clase en cuestin que son vlidos bajo este invariante. Para el resto de las expresiones-objetos (que son invlidas segn este invariante), la expresin debe evaluar en falso. Estos invariantes pueden tener una descripcin optativa (que se escribe entre corchetes). 2) Invariantes de mtodo/responsabilidad context idclase::idmetodo(par1:T1, ,parn:Tn)[:Tres] pre: [[Descripcin precondicin]] expBool post: [[Descripcin postcondicin]] expBool

Define la aplicabilidad de un mtodo/responsabilidad (de nombre idmetodo, existente dentro de la clase idclase con parmetros formales par1 a parn de tipo T1 a Tn , y con imagen de tipo Tres -slo en el caso que retorne una expresin-). La clusula pre refleja la precondicin de este mtodo/responsabilidad, expresada en la primera expresin booleana expBool, que deber retornar verdadero slo para aquellas expresiones-objetos para la cual este mtodo sea aplicable. La clusula post refleja la postcondicin de este mtodo/responsabilidad, expresada en la segunda expresin booleana expBool, que deber retornar verdadero slo cuando el estado final de la expresin-objeto al que se le aplic este mtodo/responsabilidad es consistente con el accionar del mismo. No existiran problemas si el mtodo/responsabilidad retorna una expresin y no modifica el estado interno de la expresin-objeto original, ya que la postcondicin slo verificara el resultado que retorna. Pero si no retorna un valor (porque en realidad modifica el estado interno de la expresin-objeto original), la naturaleza de la postcondicin es distinta que la anterior, ya que existe un efecto colateral de por medio. En este ltimo caso no se especifica cmo se actualiza el estado interno de la expresin-objeto original (ya que esto no sera declarativo), sino la condicin en que debe quedar la expresin-objeto original luego de aplicarle este mtodo/responsabilidad. Este invariante terminara reflejando en forma declarativa su definicin en s misma. 3) Definicin de atributos derivados context idclase::idatributo:T derive: expT Define un atributo derivado de nombre idatributo existente en la clase idclase, y que retornar una expresin de tipo T. La expresin retornada por este atributo derivado, al aplicarla sobre una expresin-objeto de la clase en cuestin, retornar la expresin expT, que tambin deber ser de tipo T. 4) Definicin de mtodos/responsabilidades derivados (queries): context idclase::idmetodo(par1:T1, ,parn:Tn):T [pre: [[Descripcin precondicin]] expBool] body: expT Define un mtodo/responsabilidad derivado Como es un mtodo/responsabilidad, el contexto es idntico al de un mtodo/responsabilidad comn, con la diferencia que siempre retornar una expresin (que deber ser de tipo T) y no provocar efectos colateriales. La clusula pre optativa determina si es aplicable o no (segn el resultado de expBool) a cada expresin-objeto de la clase. En forma anloga a los atributos derivados, en la clusula body se especifica cul ser el valor retornado para cada expresin-objeto de la clase que sea aplicable, a travs de la expresin expT, que ser de tipo T.

Tipos de datos

1) Predefinidos a) Bsicos - Boolean (valores lgicos) - Integer (valores enteros) - Real (valores reales) - String (valores de cadenas de caracteres) - OCLAny (el tipo supremo jerrquico de todos los tipos no estructurados) - OCLType (el tipo asociado a los metatipos -todo tipo puede verse como una expresin de tipo OCLType) b) Estructurados - Collection(T) - Set(T) - Bag(T) - OrderedSet(T) - Sequence(T) - Tuple{id1:T1,..., idn:Tn} El tipo Set(T) corresponde a los conjuntos de expresiones de tipo T, que no contienen repeticiones y sus expresiones contenidas no poseen un orden posicional. El tipo Bag(T) corresponde a los bags de expresiones de tipo T, que permiten contener repeticiones y donde sus expresiones contenidas no poseen un orden posicional. El tipo OrderedSet(T) corresponde a los conjuntos ordenados de expresiones de tipo T, que no contienen repeticiones y sus expresiones contenidas poseen un orden posicional. El tipo Sequence(T) corresponde a las secuencias (listas) de expresiones de tipo T, que permiten contener repeticiones y donde sus expresiones poseen un orden posicional. El tipo Collection(T) corresponde a las colecciones de expresiones de tipo T. Es un tipo que es abstracto y superior jerrquico de los cuatro anteriores. El tipo Tuple{id1:T1,..., idn:Tn} (con n>0) corresponde a las tuplas (registros/records) con campos de nombre id1 a idn , donde cada uno de ellos debe tener asociada una expresin de tipo T1 a Tn respectivamente. 2) No predefinidos Corresponden a cada clase y enumerado del diagrama de clases. Toda clase o enumerado C se mapear al tipo asociado TC de OCL. Sin embargo, como abuso de notacin es normal referirse al tipo como C (el mismo nombre de la clase), aunque no lo haremos en el resto de este apunte. Aqu expresamos al tipo de la clase C como TC slo a los efectos de distinguir la diferencia de conceptos entre clase y tipo.

En OCL cada atributo de una clase, al aplicarse a una expresin del tipo asociado a la clase, retorna una expresin que tambin tendr un tipo asociado. Con esto, decimos, que todo atributo tiene tambin un tipo asociado. Esto ya se dijo en la definicin de atributos derivados, cuando se expres que stos retornan una expresin de un tipo resultante especificado. Con esto, decimos que todo atributo atrib tiene asociado en OCL el tipo de dato Tatrib. Este tipo no es necesariamente nuevo (como en el caso de los provenientes de clases o enumerados). Al no definir un tipo necesariamente nuevo, en este apunte diremos que el tipo retornado es T. Si utilizamos el diagrama de clases dentro del contexto del diseo, seguramente cada atributo de cada clase tendr su tipo de datos asociado en forma explcita en la misma clase del diagrama, y con esto se puede mapear al tipo correspondiente de OCL. El problema que existe en el diagrama de clases del modelo conceptual es que en las clases conceptuales no se especifican tipos de datos. Esto sugiere la idea de existencia de dominios -como abstracciones respecto a los tipos- (los atributos de las clases conceptuales retornan un objeto de un dominio, en lugar de una expresin-objeto de un tipo de datos). En este caso hay que realizar un mapeo implcito de los dominios de los atributos a tipos bsicos de OCL para poder expresar condiciones en OCL que se apliquen sobre los valores retornados por estos atributos.

Constantes
1) Tipos predefinidos a) Tipos bsicos - De tipo Boolean: true, false - De tipo Integer: constantes enteras (Ej: 5, 8, -76, ...) - De tipo Real: constantes reales (Ej: -7.5, 5.9, 0.0, ...) - De tipo String: constantes string entre caracteres y (Ej: Hola, , 7*, ...) b) Tipos estructurados - De tipo Collection(T): no posee constantes porque es abstracto. - De tipo Set(T): constantes de la forma Set {exp1, exp2, ..., expn}, con n0, y donde las expresiones exp1 a expn son todas de tipo T. - De tipo Bag(T): constantes de la forma Bag {exp1, exp2, ..., expn}, con n0, y donde las expresiones exp1 a expn son todas de tipo T. - De tipo OrderedSet(T): constantes de la forma OrderedSet {exp1, exp2, ..., expn}, con n0, y donde las expresiones exp1 a expn son todas de tipo T. - De tipo Sequence(T): constantes de la forma Sequence {exp1, exp2, ..., expn}, con n0, y donde las expresiones exp1 a expn son todas de tipo T. - De tipo Tuple{id1:T1, ..., idn:Tn}: constantes de la forma Tuple {id1:T1 = exp1,..., idn:Tn = expn}, donde las expresiones exp1 a expn son todas de tipo T1

a Tn respectivamente. En general, los tipos de los campos en las expresiones de tipo tupla pueden omitirse. 2) No predefinidos Slo los tipos asociados a los enumerados del diagrama de clases poseen constantes. Si c fuera un valor dentro del enumerado E del diagrama de clases, entonces la expresin TE::c es de tipo TE. 3) Constantes especiales self: representa a cada expresin-objeto de una clase a las que se le quiere verificar una propiedad o aplicar un atributo derivado o un mtodo/responsabilidad (derivado o no). Es reconocida nicamente en las clusulas inv, pre, post, derive y body. result: representa al valor retornado por un mtodo/responsabilidad comn que retorna una expresin. Es reconocida nicamente en las clusulas post. 4) Parmetros Los parmetros de mtodos/responsabilidades (comunes o derivados) se pueden utilizar en aquellas clusulas pre, post, y body de aquellas definiciones donde aparecieron en la clusula context.

Operaciones centrales sobre tipos no predefinidos


1) Atributos (comunes o derivados) Si atrib es un atributo de la clase C que retorna una expresin de tipo T, y x es una expresin de tipo TC, entonces x.atrib es una expresin de tipo T, que retorna el valor del atributo atrib asociado a la expresin x. Se considera dentro de las posibilidades, que un atributo pueda retornar una expresin de un tipo estructurado (como por ejemplo, un conjunto). 2) Pseudoatributos de multiplicidad 1 (simple) Si psatrib es un pseudoatributo de la clase C que la asocia a la clase D, y x es una expresin de tipo TC, entonces x.psatrib es una expresin de tipo TD. Retorna la expresin del tipo TD que se asocia va el rol psatrib a la expresin x. 3) Pseudoatributos de multiplicidad 0..1, 0..*, 1..* (mltiple) Si psatrib es un pseudoatributo de la clase C que la asocia a la clase D, y x es una expresin de tipo TC, entonces x.psatrib es una expresin de tipo Set(TD). Retorna las expresiones del tipo TD que se asocian va el rol psatrib a la

expresin x. Las retorna como un set (conjunto) porque no pueden existir elementos repetidos, y no existe un orden de aparicin en la coleccin retornada. 4) Pseudoatributos de multiplicidad 0..1, 0..*, 1..* con label {ordered} Si psatrib es un pseudoatributo de la clase C que la asocia a la clase D, y x es una expresin de tipo TC, entonces x.psatrib es una expresin de tipo OrderedSet(TD). Es similar al caso anterior, y retorna a las expresiones resultantes como un orderedset (conjunto con orden posicional) porque no pueden existir elementos repetidos, y existe un orden de aparicin en la coleccin retornada (indicado por la etiqueta {ordered}). 5) Mtodos/responsabilidades (comunes o derivados) que retornan un valor Si met es un mtodo/responsabilidad de la clase C que recibe n parmetros de tipo T1 a Tn, y retorna una expresin de tipo T, y existen expresiones exp1 a expn que son de tipo T1 a Tn respectivamente, y x es una expresin de tipo TC, entonces x.met(exp1,...,expn) es una expresin de tipo T. Retorna el resultado de la aplicacin del mtodo/responsabilidad met a la expresin x, usando como parmetros a las expresiones exp1 a expn. 6) Mtodos/responsabilidades de clase (slo para contados casos) Si met es un mtodo/responsabilidad de clase de la clase C que recibe n parmetros de tipo T1 a Tn, y retorna una expresin de tipo T, y existen expresiones exp1 a expn que son de tipo T1 a Tn respectivamente, entonces Tc.met(exp1,...,expn) es una expresin de tipo T. Retorna el resultado de la aplicacin del mtodo/responsabilidad met a la clase C, usando como parmetros a las expresiones exp1 a expn. Todas estas oparaciones se pueden componer sucesivamente utilizando esta notacin. El significado de la operacin de aplicacin de atributo es obtener la expresin asociada al atributo de una expresin dada. Adems de existir expresiones de la forma x.atrib , tambin existen otras de la forma x.atrib@pre (slo dentro de las clusulas post) que representan el valor retornado por el atributo atrib aplicado a la expresin x en el momento de la evaluacin de la precondicin (el mismo valor que retornara la expresin x.atrib dentro de la clusula pre correspondiente). Esto ltimo tambin se puede utilizar para pseudoatributos de multiplicidad 1. El significado de la operacin de aplicacin de pseudoatributo es obtener la o las expresiones-objeto asociadas a una expresin dada en funcin de la asociacin con la clase de las expresiones-objeto obtenidas. Esto permite pasar de una clase a otra. A la composicin de pseudoatributos se la suele llamar informalmente navegacin por el diagrama de clases.

El significado de la operacin de aplicacin de mtodo/responsabilidad es obtener la expresin-objeto asociada a la aplicacin de este mtodo/responsabilidad.

Operaciones asociadas a los tipos bsicos predefinidos


Algunas de estas operaciones binarias se escriben sintcticamente como funciones infijas (que se escriben entre sus dos argumentos), o con la notacin postfija caracterstica de la orientacin a objetos, que se aplica al primero de sus dos argumentos, y el segundo argumento se pasa como su nico parmetro. Lo mismo ocurre con las operaciones unarias, de las que algunas se escriben con la notacin prefija funcional, y otras con la notacin postfija que se aplica a su nico argumento y no posee parmetros. 1) De tipo Boolean (exp1: Boolean and exp2: Boolean): Boolean (exp1: Boolean or exp2: Boolean): Boolean not(exp: Boolean): Boolean (exp1: Boolean xor exp2: Boolean): Boolean (exp1: Boolean implies exp2: Boolean): Boolean Representan la conjuncin (and), disyuncin (or), negacin (not), disyuncin exclusiva (xor) e implicacin material (implies). (if (exp: Boolean) then (exptrue: T) else (expfalse: T) endif): T Representa el if funcin, infijo de tres argumentos. (exp1: T = exp2: T): Boolean (exp1: T <> exp2: T): Boolean (exp1: T < exp2: T): Boolean (exp1: T <= exp2: T): Boolean (exp1: T > exp2: T): Boolean (exp1: T >= exp2: T): Boolean Representan los operadores relacionales. El tipo T no puede ser cualquiera, sino un tipo que tenga definido estos operadores. 2) De tipo Integer (exp1: Integer + exp2: Integer): Integer (exp1: Integer - exp2: Integer): Integer (exp1: Integer * exp2: Integer): Integer (exp1: Integer / exp2: Integer): Integer

Integer.abs(): Integer Integer.div(exp: Integer): Integer Integer.mod(exp: Integer): Integer Integer.min(exp: Integer): Integer Integer.max(exp: Integer): Integer Representan las operaciones de suma (+), resta (-), producto (*), cociente (/, div), valor absoluto (abs), resto (mod), mnimo (min) y mximo (max). 3) De tipo Real (exp1: Real + exp2: Real): Real (exp1: Real - exp2: Real): Real (exp1: Real * exp2: Real): Real (exp1: Real / exp2: Real): Real Real.floor(): Real Real.round(exp: Integer): Real Representan las operaciones de suma (+), resta (-), producto (*), cociente (/), parte entera -o mayor nmero entero devuelto como nmero real que es menor o igual al nmero real dado- (floor) y valor redondeado a una cantidad de decimales dada (round). 4) De tipo String String.size(): Integer String.concat(exp: String): String String.substring(exp1, exp2: Integer): String String.toUpper(): String String.toLower(): String String.toInteger(): Integer String.toReal(): Real Representan las operaciones de cantidad de caracteres -longitud- (size), concatenacin de dos cadenas (concat), obtencin de una subcadena de una cadena dada desde una determinada posicin tomando una cierta cantidad de caracteres a partir de all (substring), la conversin a maysculas (toUpper), a minsculas (toLower), a entero (toInteger) y a real (toReal).

Operaciones asociadas a los tipos de Coleccin


Las operaciones de coleccin se aplican siempre sobre una expresin de tipo Collection (o de alguno de sus cuatro subtipos concretos), y pueden o no tener parmetros. La expresin de tipo coleccin que es receptora de esta operacin se escribe antes de la

operacin. Entre la coleccin receptora y la operacin debe ir el smbolo -> (que reemplazara en este caso al caracter . tradicional). El operador -> , como el . , tambin se puede componer sucesivamente. Como siempre, las aplicaciones de estas operaciones no provocan efectos colaterales. Esta es la lista de operaciones existentes: Collection(T)->size(): Integer Retorna la cantidad de elementos que posee la coleccin. Collection(T)->empty(): Boolean Retorna si la coleccin est vaca (no contiene elementos). Collection(T)->notEmpty(): Boolean Retorna si la coleccin no est vaca (contiene algn elemento). Collection(T)->includes(exp: T): Boolean Retorna si la expresin pasada como parmetro pertenece a la coleccin. El tipo T debe poseer la igualdad y la desigualdad. Collection(T)->excludes(exp: T): Boolean Retorna si la expresin pasada como parmetro no pertenece a la coleccin. El tipo T debe poseer la igualdad y la desigualdad. Collection(T)->includesAll(exp: Collection(T)): Boolean Retorna si la expresin-coleccin pasada como parmetro est includa en la coleccin original. El tipo T debe poseer la igualdad y la desigualdad. Collection(T)->excludesAll(exp: Collection(T)): Boolean Retorna si la expresin-coleccin pasada como parmetro es disjunta respecto a la coleccin original. El tipo T debe poseer la igualdad y la desigualdad. Collection(T)->sum(): Integer Retorna si la suma de los elementos que componen la coleccin. El tipo T debe poseer la operacin de suma. Set(T)->including(exp: T): Set(T) Bag(T)->including(exp: T): Bag(T)

OrderedSet(T)->including(exp: T): OrderedSet(T) Sequence(T)->including(exp: T): Sequence(T) Retorna una coleccin que es la misma que la original, con el agregado de un nuevo elemento, indicado por la expresin dada. El tipo de la coleccin retornada es el mismo que el de la original. Set(T)->union(exp: Set(T)): Set(T) Set(T)->union(exp: Bag(T)): Bag(T) Bag(T)->union(exp: Set(T)): Bag(T) Bag(T)->union(exp: Bag(T)): Bag(T) OrderedSet(T)->union(exp: OrderedSet(T)): OrderedSet(T) OrderedSet(T)->union(exp: Sequence(T)): Sequence(T) Sequence(T)->union(exp: OrderedSet(T)): Sequence(T) Sequence(T)->union(exp: Sequence(T)): Sequence(T) Retorna la unin de dos colecciones. Se asume que si alguna de las dos es de un tipo que admite repeticiones, entonces la coleccin retornada podr contener repeticiones. Set(T)->intersection(exp: Set(T)): Set(T) Set(T)->intersection(exp: Bag(T)): Set (T) Bag(T)->intersection(exp: Set(T)): Set (T) Bag(T)->intersection(exp: Bag(T)): Bag(T) OrderedSet(T)->intersection(exp: OrderedSet(T)): OrderedSet(T) OrderedSet(T)->intersection(exp: Sequence(T)): OrderedSet(T) Sequence(T)->intersection(exp: OrderedSet(T)): OrderedSet(T) Sequence(T)->intersection(exp: Sequence(T)): Sequence(T) Retorna la interseccin de dos colecciones. Se asume que si alguna de las dos es de un tipo que no admite repeticiones, entonces la coleccin retornada no podr contener repeticiones. Set(Collection(T))->flatten(): Set(T) Bag(Collection(T))->flatten(): Bag(T) OrderedSet(Collection(T))->flatten(): OrderedSet(T) Sequence(Collection(T))->flatten():Sequence(T) Retorna el aplanado de una coleccin de colecciones, eliminando un nivel de colecciones. Dicho de otra forma, retorna la concatenacin de todos los elementos de la coleccin de colecciones original (que son colecciones). El tipo mandatorio de la coleccin resultante es el ms "externo". Las siguientes operaciones son de orden superior, ya que como parmetro de estas operaciones se especifican funciones implcitas representadas por una variable ligada

(bounded variable) y una expresin-cuerpo que admite apariciones libres de la variable ligada especificada (y que hace referencia a ella misma). Collection(T)->forAll(var | exp: Boolean): Boolean Retorna si todos los elementos de la coleccin original cumplen con la condicin dada. La condicin se expresa en el parmetro de esta operacin, usando una variable ligada (var) que se instancia con cada elemento de la coleccin, y la condicin a testear sobre cada una de ellos (expresin lgica exp). Esta expresin admite apariciones libres de la variable var. Collection(T)->forAll(var1, var2 | exp: Boolean): Boolean Retorna lo mismo que la siguiente expresin (suponiendo que c es una expresin de tipo Collection(T)): c->forAll(var1 | c->forAll(var2 | exp)) Set(T)->select(var | exp: Boolean): Set(T) Bag(T)->select(var | exp: Boolean): Bag(T) OrderedSet(T)->select(var | exp: Boolean): OrderedSet(T) Sequence(T)->select(var | exp: Boolean): Sequence(T) Retorna a todos los elementos de la coleccin original que cumplen con la condicin dada en el parmetro. La variable ligada se vincula a cada elemento de la condicin, y la expresin lgica retorna si el elemento dado queda o no en la coleccin resultante. La coleccin resultante ser del mismo tipo que la original. Set(T)->reject(var | exp: Boolean): Set(T) Bag(T)->reject(var | exp: Boolean): Bag(T) OrderedSet(T)->reject(var | exp: Boolean): OrderedSet(T) Sequence(T)->reject(var | exp: Boolean): Sequence(T) Retorna a todos los elementos de la coleccin original que no cumplen con la condicin dada en el parmetro. Set(T1)->collect(var | exp: T2): Bag(T2) Bag(T1)->collect(var | exp: T2): Bag(T2) OrderedSet(T1)->collect(var | exp: T2): Sequence(T2) Sequence(T1)->collect(var | exp: T2): Sequence(T2) Retorna un mapeo de todos los elementos de la coleccin orginal a una coleccin resultante de la misma cantidad de elementos, donde cada elemento de la coleccin resultante es el mapeado de la misma posicin en la coleccin original (si posee orden posicional). La funcin de mapeo se expresa con la variable ligada (que se sustituye por cada elemento de la coleccin original) y la expresin-cuerpo que indica el valor a retornar

en la coleccin resultante para la expresin original dada. El tipo de la expresin-cuerpo ser el mismo que el de los elementos de la coleccin resultante. Como luego de la aplicacin de esta operacin se pueden generar elementos repetidos en la coleccin resultante que provienen de elementos distintos de la coleccin original, se asume que la coleccin resultante debe admitir repetidos (de ah que no se retornan conjuntos), para lograr mantener la misma cantidad de elementos respecto a la cantidad de elementos de la coleccin original. Collection(T1)->isUnique(var | exp: T2): Boolean Retorna si todos los elementos de la coleccin, al mapearse cada uno de ellos al mapeo propuesto (anlogo a la operacin collect) da como resultado una coleccin con todos valores distintos (dos a dos). El tipo T2 debe poseer la igualdad y desigualdad. Collection(T)->iterate(var1 ; var2: T2 = expinicial | exp: T2): T2 Retorna la aplicacin sucesiva de la funcin binaria de variables ligadas (var1,var2) y cuerpo exp, iterando por cada uno de los valores de la coleccin original -que son los valores usados en la sustitucin de la variable var1- y donde cada resultado parcial indicado en la expresin exp- se usa como parmetro-acumulador del paso siguiente -en la variable var2-. El valor resultado original ser dado en la expresin expinicial. El tipo T2 que se escribe luego de la variable var2 debe ser obligatorio. Ms fcilmente, el resultado de esta operacin se ve reflejado por el siguiente pseudoalgoritmo (donde la coleccin original est indicada por la variable c): res := expinicial paraCada i indice de c res := ((var1,var2) exp) (c[i],res) fin-paraCada retornar res la expresin de la parte derecha de la asignacin del rengln 3 significa la aplicacin de una funcin de dos parmetros. Esta operacin es anloga a la funcin foldl del lenguaje funcional Haskell. Todos los mtodos de coleccin que reciben parmetros de la forma (var | exp) (como por ejemplo select, reject o collect) pueden ser escritos con otra sintaxis, a saber: Collection(T)->operacion(var | exp) Collection(T)->operacion(var: T | exp) Collection(T)->operacion(exp) El segundo caso es anlogo al primero, con la diferencia de que se puede realizar un typecast sobre el tipo de los elementos de la coleccin por un subtipo de ste (similar al uso de la operacin OCLasType que se comentar despus). Los vnculos de variables

reconocidos en la expresin exp son los reconocidos por el contexto de la expresin general ms la variable var. En el tercer caso, la variable var no aparece, y no puede aparecer libre como subexpresin de la expresin exp. En exp todos los mtodos/responsabilidades, atributos y pseudoatributos aplicados a un receptor no especificado, son asumidos que se aplican en primera instancia a cada elemento de la coleccin, y en segunda instancia, a self. Si hubiera algn problema de ambigedad, no se puede elegir esta opcin de sintaxis, y se debe optar por alguna de las dos primeras. Lo ms comn para este caso es que exp sea un atributo o pseudoatributo y la operacin en cuestin sea collect. Como caso aparte, en la operacin forAll con el iterador sobre pares de elementos de la coleccin dada, la expresin booleana del cuerpo del mtodo puede contener apariciones libres de estas dos variables ligadoras, y que se ligaran a stas. Notacin de punto aplicada a colecciones: Existe la notacin de aplicaciones de atributos y pseudoatributos a colecciones con la notacin del punto (aplicados como si no fueran colecciones). La definicin es la siguiente: Si c es una expresin de tipo Collection(T) y psatrib es un pseudoatributo (o atributo) sobre el tipo T, se define lo siguiente:

c.psatrib

c->collect(psatrib) c->collect(psatrib)->flatten()

(si psatrib no es PAM) (si psatrib es PAM)

PAM es el resumido de pseudoatributo mltiple.

Operaciones asociadas a colecciones especficas


(exp1: Set(T) - exp2: Set(T)): Set(T) Retorna la diferencia entre dos conjuntos. Set(T)->symmetricDifference(exp: Set(T)): Set(T) Retorna la diferencia simtrica entre dos conjuntos. Bag(T)->count(exp: T): Integer Sequence(T)->count(exp: T): Integer

Retorna la cantidad de apariciones de la expresin dada en la coleccin. El tipo T debe tener definida la operacin de igualdad. Bag(T)->asSet(): Set(T) OrderedSet(T)->asSet(): Set(T) Sequence(T)->asSet(): Set(T) Retorna la conversin de la coleccin dada en un Set. En el Set resultante el orden posicional y la cantidad de apariciones se pierden. Set(T)->asBag(): Bag(T) OrderedSet(T)->asBag(): Bag(T) Sequence(T)->asBag(): Bag(T) Retorna la conversin de la coleccin dada en un Bag. En el Bag resultante el orden posicional se pierde, y la cantidad de apariciones resultantes de los elementos si la coleccin original es un conjunto es 1 para todos. Set(T)->asOrderedSet(): OrderedSet(T) Bag(T)->asOrderedSet(): OrderedSet(T) Sequence(T)->asOrderedSet(): OrderedSet(T) Retorna la conversin de la coleccin dada en un OrderedSet. En el OrderedSet resultante la cantidad de apariciones se pierden, y el orden posicional de los elementos si la coleccin original no tiene orden se crea con el orden natural sobre el tipo T (el tipo T debe tener definida la operacin menor o igual). Set(T)->asSequence():Sequence(T) Bag(T)->asSequence(): Sequencet(T) OrderedSet(T)->asSequence(): Sequence(T) Retorna la conversin de la coleccin dada en una Sequence. Sobre la Sequence resultante se crea el orden posicional con el orden natural sobre el tipo T si la coleccin original no era ordenada, y crea la cantidad de apariciones de los elementos en 1 si la coleccin original era un conjunto. OrderedSet(T)->first(): T Sequence(T)->first(): T Retorna el primer elemento de la coleccin con orden posicional (si es que existe). OrderedSet(T)->last(): T Sequence(T)->last(): T Retorna el ltimo elemento de la coleccin con orden posicional (si es que existe).

OrderedSet(T)->at(exp: Integer): T Sequence(T)->at(exp: Integer): T Retorna el elemento de la posicin exp dada de la coleccin con orden posicional (si es que existe). Sequence(T)->append(exp: Sequence(T)): Sequence(T) Retorna la concatenacin de la secuencia exp luego de la secuencia original. Sequence(T)->prepend(exp: Sequence(T)): Sequence(T) Retorna la concatenacin de la secuencia exp antes de la secuencia original. Sequence(T)->subSequence(exp1, exp2: Integer): Sequence(T) Retorna la subsecuencia de la secuencia original que comienza en la posicin exp1, y posee exp2 cantidad de elementos a partir de all.

Jerarqua de tipos
Los tipos de datos se encuentran jerarquizados a travs del concepto de inclusin. Los tipos includos heredan todas las propiedades (atributos, peudoatributos y mtodos/responsabilidades) de sus tipos superiores (los que lo incluyen). La relacin de inclusin estricta este tipos se refleja con el siguiente operador: T1 < T2 si y slo si T1 es un subtipo estricto de T2 Las reglas propias del operador < de inclusin de tipos son las siguientes: - Si A es una clase y B es una subclase de A en el diagrama de clases, entonces TB < TA - T < OCLAny (para todo tipo T no estructurado) - T1 < T2 Set(T1) < Set(T2) - T1 < T2 Bag(T1) < Bag(T2) - T1 < T2 OrderedSet(T1) < OrderedSet(T2) - T1 < T2 Sequence(T1) < Sequence(T2) - Set(T) < Collection(T) - Bag(T) < Collection(T) - OrderedSet(T) < Collection(T) - Sequence(T) < Collection(T) - Integer < Real - T : OCLType

- T1 < T2 y T2 < T3 T1 < T3 Se aceptan mltiples jerarquas asociadas a una misma clase, al igual que la existencia de herencia mltiple (ya que estas dos caractersticas son aceptadas en el diagrama de clases).

Operacin de tuplas
Las campos de una tupla se comportan como si fueran atributos. Estos campos se utilizan sobre una tupla para proyectar sus valores. O sea que vale lo siguiente: Si x es una expresin de tipo Tuple{id1:T1, ..., idn:Tn}, entonces x.idi es una expresin de tipo Ti.

Operaciones de clase
Dada una clase C del diagrama de clases, se le puede aplicar la siguiente operacin de clase: TC.allInstances(): Set(TC) Retorna el conjunto de todas las expresiones-objeto de la clase C. Existen otras operaciones que se aplican a cualquier clase, relacionadas con metainformacin. Estas se aplican en realidad sobre las expresiones-objeto del tipo de las clases del modelo, que son las expresiones del tipo OCLType. Estas son las operaciones: OCLType.name(): String Retorna el nombre de la clase. OCLType.attributes(): Set(String) Retorna el conjunto de los nombres de todos los atributos de la clase. OCLType.associationEnds(): Set(String) Retorna el conjunto de los nombres de todos los pseudoatributos (roles) de la clase. OCLType.operations(): Set(String) Retorna el conjunto (mtodos/responsabilidades). de los nombres de todas las operaciones

OCLType.supertypes(): Set(OCLType) Retorna el conjunto de los tipos inmediatamente superiores a la clase. OCLType.allSupertypes(): Set(OCLType) Retorna el conjunto de los tipos superiores a la clase (los inmediatamente superiores y sus antipos ancestros).

Expresiones LET
Existe otro tipo de expresiones, muy utilizada para no repetir o simplificar evaluaciones. Son las expresiones LET, que son expresiones con la siguiente sintaxis: let var: T = exp1 in exp2 La evaluacin de esta expresin let consta de la evaluacin de la expresin exp2, reemplazando antes todas las apariciones libres de la variable var (que dentro de exp2 es usada como expresin) por la expresin exp1. El tipo de var (T) debe especificarse, y debe coincidir con el tipo del la expresin exp1. Dentro de la expresin exp2 se reconocen como expresiones a las vinculaciones a variables reconocidas en el contexto de la expresin let, y a esta nueva variable var (que slo es local a la expresin let).

En relacin a la creacin de expresiones-objetos de una clase


La creacin de objetos de una clase es una operacin de naturaleza destructiva. Es por eso que stas no se modelan con OCL, que es declarativo. Lo que s se puede hacer con OCL es verificar o establecer caractersticas de los objetos en funcin de su creacin. Para ello se puede utilizar la siguiente operacin: OCLAny.OCLisNew(): Boolean Este mtodo (que se puede utilizar nicamente en la clusula post de la especificacin de un mtodo/resposabilidad), retorna si la expresin-objeto receptora del mensaje fue recientemente creada (durante la ejecucin del mismo mtodo -que no es especificado en OCL-). Relacionado con esto, en OCL se permite especificar el valor que tendr un atributo o pseudoatributo de un objeto inmediatamente despus del momento de su creacin. Esto se hace con una nueva clusula init, donde se especifican los valores iniciales de atributos y pseudoatributos de objetos recientemente creados. El contexto utilizado es un atributo o

pseudoatributo propio de una clase, caracterstico de todas las instancias de esa misma clase. Esta es su sintaxis: context idclase::idatributo:T init: expT Con esto se especificar que el valor inicial que tendr el atributo o pseudoatributo idatributo (de tipo T) para objetos recientemente creados pertenecientes a la clase dada, ser la expresin expT (que tambin debe ser de tipo T). Como est permitido especificar valores iniciales tambin para los pseudoatributos, se podrn retornar expresiones de un tipo estructurado de alguna coleccin. Tambin se pueden especificar valores iniciales de algn tipo de tupla. Dentro de la expresin expT se puede utilizar la expresin self (hacer una referencia al objeto recientemente creado), siempre y cuando de l se obtengan valores de atributos o pseudoatributos, para los cuales su valor inicial haya sido especificado en una clusula init anterior.

Sobre el uso de las clases de asociacin del diagrama de clases


Sean A y B clases, y C una clase de asociacin entre A y B (vamos a llamar tambin TA, TB y TC a los tipos asociados a las clases A, B y C respectivamente). Sean expA, expB y expC expresiones de tipos TA, TB y TC respectivamente, y dado el siguiente diagrama:

Valen las siguientes expresiones (ya vistas desde el comienzo): expA.rol2 retorna una expresin de tipo Set(TB). expB.rol1 retorna una expresin de tipo TA. Adems de este caso, dentro del contexto de dos clases que se encuentran asociadas (A y B en este caso), se puede usar el nombre de la clase de asociacin como pseudoatributo de los tipos de las dos clases asociadas por esa asociacin. Lo retornado en este ltimo caso son aquel o aquellas instancias de la asociacin (como si fueran pares) que poseen el valor

de la expresin del tipo de la clase origen, pero vistas como expresiones-objeto pertenecientes al tipo de la clase de asociacin (TC). La multiplicidad de este pseudoatributo-clase de asociacin es la misma que la multiplicidad del rol destino de la misma asociacin. O sea que tambin vale lo siguiente: expA.C retorna una expresin de tipo Set(TC). expB.C retorna una expresin de tipo TC. Por otro lado, dentro del contexto de un tipo-clase de asociacin, para toda expresinobjeto de ese tipo, se puede obtener con qu expresiones de los dos tipos asociados se asocia (siempre ser de multiplicidad 1). Para esto se utiliza como pseudoatributo los nombres de los roles de la relacin original. O sea que vale: expC.rol1 retorna una expresin de tipo TA. expC.rol2 retorna una expresin de tipo TB. Existe un caso que vale la pena distinguirlo, que es cuando la asociacin se presenta entre una clase A y s misma (no existira una clase B). Este sera el caso:

El problema ocurre con las referencias al pseudoatributo-clase de asociacin C dentro del contexto de la clase A, ya que habra que hacer explcito el rol origen de las expresiones-objeto del tipo de la clase A a las que se refiere. Esto se hace escribiendo entre corchetes el rol dentro de la asociacin: expA.rol2 retorna una expresin de tipo Set(TA). expA.rol1 retorna una expresin de tipo TA. expA[rol1].C retorna una expresin de tipo Set(TC)(toma a expA desde rol1). expA[rol2].C retorna una expresin de tipo TC (toma a expA desde rol2).

Sobre el uso de la herencia


Como OCL es tipado y existe una jerarqua de tipos (basado en herencia mltiple, que es la del diagrama de clases), entonces se aplican las reglas de covarianza y contravarianza presente en los chequeos de tipos de los lenguajes de programacin orientados a objetos (Eiffel, Java, Object Pascal, etc).

Al tener como una de las vetas principales a la orientacin a objetos, se aceptan las reglas de herencia (todas los tipos heredan los atributos, mtodos y pseudoatributos de sus supertipos). Tambin se aceptan las reglas de sobrecarga de mtodos en subtipos. Esto ltimo no es definitorio de la orientacin a objetos, pero se usa en todos los conceptos relacionados con la orientacin a objetos. Existen varias operaciones aplicables a cualquier tipo de expresin muy relacionadas con el concepto de herencia y con la idea de tratar a los tipos de datos como datos propiamente dichos (ya se mencion antes de OCLType, que es el metatipo), como por ejemplo, expresar expresiones lgicas de la forma el tipo de la expresin var45 es Set(Integer). Esto se relaciona con la idea de que una expresin es de un tipo, pero tambin es de todos los supertipos de se (por el polimorfismo de inclusin propio de la herencia). Estas operaciones son: OCLAny.OCLisKindOf(exp: OCLType): Boolean Retorna si el tipo de la expresin receptora (de tipo OCLAny) es exp o subtipo de exp. OCLAny.OCLisTypeOf(exp: OCLType): Boolean Retorna si el tipo de la expresin receptora (de tipo OCLAny) es idntico a exp. T1.OCLasType(T2: OCLType): T2 Retorna la misma expresin recibida (de tipo T1), aunque se asume que el tipo de esta expresin retornada es de tipo T2. Representa el typecast elegante de la orientacin a objetos, donde debe ocurrir que T2 < T1. El objetivo del uso de esta operacin es poder aplicar algn atributo, pseudoatributo o mtodo/responsabilidad de un subtipo del tipo de la expresin si se sabe con seguridad que tambin pertenece a ese subtipo.

Sobre la recursin y los valores indefinidos


En OCL se permite utilizar recursin en todos las definiciones que se necesiten. Dependiendo de la semntica de los mtodos/responsabilidades, la aplicacin de stos a expresiones pueden retornar valores indefinidos. Todos los mtodos/responsabilidades, atributos y pseudoatributos se consideran estrictos, con lo que si uno de sus parmetros (o la expresin-objeto receptora) es indefinida (<undefined>), su resultado tambin ser indefinido. Existen muy pocos casos donde no existe estrictez, y est relacionado a operaciones sobre los valores lgicos, a saber: if true then r else <undefined> endif = r if false then <undefined> else r endif = r

true or <undefined> = true false and <undefined> = false false implies <undefined> = true Relacionado con este tema, se puede utilizar la siguiente operacin: OCLAny.OCLisUndefined(): Boolean Retorna si la expresin receptora (de tipo OCLAny) es indefinida. Se usa bsicamente para la captura de errores.

Bibliografa
- UML 2.0 OCL Specification (documento de la OMG publicado en Internet en http:// www.omg.org/docs/ptc/03-10-14.pdf). - Object Constraint Language Specification (documento de Internet ubicado en http://umlcenter.visual-paradigm.com/umlresources/obje_11.pdf). - Muchos otros documentos extrados de Internet.

Potrebbero piacerti anche