Está en la página 1de 14

Diagrama de Clases

Introduccin: La tcnica del diagrama de clase se ha vuelto medular en los mtodos orientados a objetos. Virtualmente, todos los mtodos han incluido alguna variacin de esta tcnica. El diagrama de clase, adems de ser de uso extendido, tambin est sujeto a la ms amplia gama de conceptos de modelado. Aunque los elementos bsicos son necesarios para todos, los conceptos avanzados se usan con mucha menor frecuencia. Por eso, he dividido mi estudio de los diagramas de clase en dos partes; los fundamentos (en el presente captulo) y los conceptos avanzados los conceptos avanzados (vase el captulo siguiente). El diagrama de clase describe los tipos de objetos que hay en el sistema y las diversas clases de relaciones estticas que existen entre ellos. Hay dos tipos principales de relaciones estticas:
y y

Asociaciones (por ejemplo, un cliente puede alquilar diversas videocintas). Subtipos (una enfermera es un tipo de persona).

Los diagramas de clase tambin muestran los atributos y operaciones de una clase y las restricciones a que se ven sujetos, segn la forma en que se conecten los objetos. Los diversos mtodos OO utilizan terminologas diferentes (y con frecuencia antagnicas) para estos conceptos. Se trata de algo sumamente frustrante pero inevitable, dado que los lenguajes OO son tan desconsiderados como los mtodos. Es en esta rea que el UML aportar algunos de sus mayores beneficios, al simplificar estos diferentes diagramas.

Diagrama de Clase Tpico

Perspectivas
Antes de empezar a describir los diagramas de clase, quisiera sealar una importante sutileza sobre el modo en que se usan. Tal sutileza generalmente no est documentada, pero tiene sus repercusiones en el modo en que debe interpretarse un diagrama, ya que se refiere a lo que se va a describir con un modelo. Siguiendo la recomendacin de Steve Cook y John Daniels (1994), considero que hay tres perspectivas que se pueden manejar al dibujar diagramas de clase (o, de hecho, cualquier modelo, aunque esta divisin se advierte de modo especial en relacin con los diagramas de clase).
y

Conceptual. Si se adopta la perspectiva conceptual, se dibuja un diagrama que represente los conceptos del dominio que se est estudiando. Estos conceptos se relacionan de manera natural con las clases que los implementan, pero con frecuencia no hay una correlacin directa. De hecho, los modelos conceptuales se deben dibujar sin importar (o casi) el software con que se implementarn, por lo cual se pueden considerar como independientes del lenguaje. (Cook y Daniels llaman perspectiva esencial a esto; por mi parte, empleo el trmino" conceptual", pues se ha usado durante mucho tiempo.) Especificacin. Ahora estamos viendo el software, pero lo que observamos son las interfaces del software, no su implementacin, por tanto, en realidad vemos los tipos, no las clases. El desarrollo orientado a objetos pone un gran nfasis en la diferencia entre interfaz e implementacin, pero esto con frecuencia se pasa por alto en la prctica, ya que el concepto de clase en un lenguaje OO combina tanto la interfaz como la implementacin. As, a menudo se hace referencia a las interfaces como tipos y a la implementacin de esas interfaces como clases. Influidos por este manejo del lenguaje, la mayor parte de los mtodos han seguido este camino. Esto est cambiando (Java y CORBA tendrn aqu cierta influencia), pero no con suficiente rapidez. Un tipo representa una interfaz que puede tener muchas implementaciones distintas debido, por ejemplo, al ambiente de implementacin, caractersticas de desempeo y proveedor. La distincin puede ser muy importante en diversas tcnicas de diseo basadas en la delegacin. Implementacin. Dentro de esta concepcin, realmente tenemos clases y exponemos por completo la implementacin. sta es, probablemente, la perspectiva ms empleada, pero en muchos sentidos es mejor adoptar la perspectiva de especificacin.

La comprensin de la perspectiva es crucial tanto para dibujar como para leer los diagramas de clase. Desdichadamente, las divisiones entre las perspectivas no son tajantes y la mayora de los modeladores no se preocupa por definidas con claridad cuando las dibujan. Cuando usted dibuje un diagrama, hgalo desde el punto de vista de una sola perspectiva clara. Cuando lea un diagrama, asegrese de saber desde qu perspectiva se dibuj. Dicho conocimiento es esencial si se quiere interpretar correctamente el diagrama. La perspectiva no es parte del UML formal, pero considero que es extremadamente valiosa al modelar y revisar los modelos. El UML se puede utilizar con las tres perspectivas. Mediante el etiquetado de las clases con un estereotipo , se puede dar una indicacin clara de la perspectiva. Las clases se marcan con clase de implementacin para mostrar la perspectiva de implementacin y con tipo para el caso de la perspectiva de especificacin y la conceptual. La mayor parte de los usuarios de los mtodos OO adopta una perspectiva de

implementacin, lo cual es de lamentar, porque las otras perspectivas con frecuencia son ms tiles. TABLA Terminologa de diagramas de clase UML Booch Coad Jacobson Odell Rumbaugh Shlaer/ Mellor Clase Clase Asociacin Usa Generalizacin Agregacin Hereda Espec-gen Contiene Parte-todo Consiste en Composicin

Clase y objeto Conexin de instancias Objeto

Asociacin por reconocimiento Hereda Subtipo

Tipo de objeto Relacin Clase Objeto Asociacin Relacin

Generalizacin Agregacin Subtipo N/A

ASOCIACIONES
Las asociaciones representan relaciones entre instancias de clases (una persona trabaja para una empresa; una empresa tiene cierta cantidad de oficinas). Desde la perspectiva conceptual, las asociaciones representan relaciones conceptuales entre clases. El diagrama indica que un Pedido debe venir de un solo Cliente y que un Cliente puede hacer varios Pedidos en un periodo de tiempo. Cada uno de estos Pedidos tie varias ne instancias de Lnea de pedido, cada una de las cuales se refiere a un solo Producto. Cada asociacin tiene dos papeles; cada papel es una direccin en la asociacin. De este modo, la asociacin entre Cliente y Pedido contiene dos papeles: uno del Cliente al Pedido; el segundo del Pedido al Cliente. Se puede nombrar explcitamente un papel mediante una etiqueta. En este caso, el papel en sentido Pedido a Lnea de orden se llama Artculos de lnea. Si no hay etiqueta, el papel se puede nombrar de acuerdo con la etiqueta de la clase; de esta forma, el papel de Pedido a Cliente se llamar Cliente (en este libro, me refiero a la clase de donde parte el papel como origen y a la clase a donde va el papel como destino. Esto significa que hay un papel de Cliente cuyo origen es Pedido y cuyo destino es Cliente). Un papel tiene tambin una multiplicidad, la cual es una indicacin de la cantidad de objetos que participarn en la relacin dada. En la Figura 4-1, la [*] entre Cliente y Pedido indica que el primero puede tener muchas ordenes asociadas a l; el [1] indica que un Pedido viene de un solo Cliente. En general, la multiplicidad indica los lmites inferior y superior de los objetos participantes. El [*] representa de hecho el intervalo [0.."infinito"]: El Cliente no necesita haber colocado un Pedido, y no hay un tope superior (por lo menos en teora) para la cantidad de pedidos que puede colocar. El [1] equivale a [1..1]: cada Pedido debe haber sido solicitado por un solo Cliente.

En la prctica, las multiplicidades ms comunes son [1], [*], y [0..1] (se puede no tener ninguno o bien tener uno). Para una multiplicidad ms general, se puede tener un solo nmero (por ejemplo, [11] jugadores en un equipo de ftbol), un intervalo (por ejemplo, [2..4] para los participantes de un juego de canasta) o combinaciones discretas de nmeros e intervalos (por ejemplo, [2, 4] para las puertas de un automvil). La Figura muestra las notaciones de cardinalidad del UML y de los principales mtodos preUML.

Dentro de la perspectiva de la especificacin, las asociaciones representan responsabilidades. La figura de diagramada de clase significa que hay uno o ms mtodos asociados con Cliente que me proporcionarn los pedidos que ha colocado un Cliente dado. Del mismo modo, existen mtodos en Pedido que me permitirn saber qu Cliente coloc tal Pedido y cuales son los Artculos de lnea que contiene un Pedido. Si existen convenciones estndar para nombrar mtodos de consulta, probablemente sus nombres se puedan deducir del diagrama. Por ejemplo, puedo tener una convencin que diga que las relaciones de un solo valor se implementan con un mtodo que devuelve el objeto relacionado y que las relaciones de varios valores se implementan mediante una enumeracin (iterador) en un conjunto de objetos relacionados. Al trabajar con una convencin de nombres como sta en Java, por ejemplo, puedo deducir la siguiente interfaz para una clase de Pedido:
class Pedido { public Cliente cliente(); // Enumeracin de lneas de Pedido public Enumeration lineaspedido() ;

Las convenciones de programacin, por supuesto, variarn de acuerdo con el lugar y no indicarn todos los mtodos, pero le sern a usted de gran utilidad para encontrar el camino. La figura de diagrama de clase implica tambin cierta responsabilidad al poner al da la relacin. Debe haber algn modo de relacionar el Pedido con el Cliente. De nuevo, no se muestran los detalles; podra ser que se especifique el Cliente en el constructor del Pedido. O, tal vez, exista un mtodo agregarPedido asociado al Cliente. Esto se puede hacer ms explcito aadiendo operaciones al cuadro de clase (tal y como veremos ms adelante). Sin embargo, estas responsabilidades no implican una estructura de datos. A partir de un diagrama a nivel de especificacin, no puedo hacer suposicin alguna sobre la estructura de datos de las clases. No puedo, ni debo poder decir si la clase Pedido contiene un apuntador a Cliente, o si la clase Pedido cumple su responsabilidad ejecutando algn cdigo de seleccin que pregunte a cada Cliente si se refiere a un Pedido dado. El diagrama slo indica la interfaz, y nada ms. Si ste fuera un modelo de implementacin, ahora daramos a entender con ello que hay apuntadores en ambos sentidos entre las clases relacionadas. El diagrama dira entonces que Pedido tiene un campo que es un conjunto de apuntadores hacia Lnea de pedido y tambin un apuntador a Cliente. En Java, podramos deducir algo como lo que exponemos a continuacin:
class Pedido { private Cliente _cliente; private Vector _lineaspedido; class Cliente { private Vector _pedidos;

En este caso, no podemos inferir nada sobre la interfaz a partir de las asociaciones. Esta informacin nos la daran las operaciones sobre la clase. Ahora vase la Figura Diagrama de clase con navegabilidades. Es bsicamente la misma que la Figura Diagrama de clase, a excepcin de que he aadido un par de flechas a las lneas de asociacin. Estas lneas indican navegabilidad. En un modelo de especificacin, esto indicara que un Pedido tiene la responsabilidad de decir a qu Cliente corresponde, pero un Cliente no tiene la capacidad correspondiente para decir cules son los pedidos que tiene. En lugar de responsabilidades simtricas, aqu tenemos responsabilidades de un solo lado de la lnea. En un diagrama de implementacin se indicara qu Pedido contiene un apuntador a Cliente pero Cliente no apuntara a Pedido.

Como se podr apreciar, la navegabilidad es una parte importante de los diagramas de implementacin y especificacin. Sin embargo, no pienso que la navegabilidad tenga utilidad en los diagramas conceptuales. Frecuentemente ver diagramas conceptuales que primero no tendrn navegabilidades. Posteriormente, se agregarn las navegabilidades como parte del cambio a perspectivas de especificacin y de implementacin. Ntese tambin, que las navegabilidades posiblemente sern diferentes entre la especificacin y la implementacin. Si existe una navegabilidad en una sola direccin, a la asociacin se le llamaasociacin unidireccional. Una asociacin bidireccional contiene navegabilidades en ambas direcciones. El UML dice que las asociaciones sin flechas significan que la navegabilidad es desconocida o que la asociacin es bidireccional. El proyecto debe definirse en el sentido de uno u otro de los significados. Las asociaciones bidireccionales incluyen una restriccin adicional, que consiste en que ambos papeles son inversos entre ellos. Esto es igual al concepto de funciones inversas en las matemticas. En el contexto de la Figura Diagrama de clase con navegabilidades, esto significa que cada Artculo de lnea asociado con un Pedido se debe asociar con el Pedido original. De modo similar, si se toma una Lnea de pedido y se busca en los artculos de lnea el

Pedido asociado, se deber ver la Lnea de pedido original en el conjunto. Esta cualidad se mantiene verdadera en las tres perspectivas. Hay varias maneras de nombrar las asociaciones. A los modeladores de datos tradicionales les gusta denominar a una asociacin con un verbo, de modo que se pueda emplear la relacin en una oracin. La mayora de los modeladores de objetos prefieren valerse de sustantivos para denominar uno u otro papel, pues esta forma corresponde mejor a las responsabilidades y operaciones. Algunos les dan nombres a todas las asociaciones. Yo prefiero nombrar las asociaciones slo cuando mejora la comprensin. He visto demasiadas asociaciones con nombres como "tiene" o "se relaciona con". Si no existe un nombre para el papel, considero que su nombre es el de la clase sealada, como indiqu antes. ATRIBUTOS Los atributos son muy parecidos a las asociaciones. Desde un nivel conceptual, el atributo de nombre de un Cliente indica que los Clientes tienen nombres. Desde el nivel de especificacin, este atributo indica que un objeto Cliente puede decir su nombre y tiene algn modo de establecer un nombre. En el nivel de implementacin, un Cliente tiene un campo (tambin llamado variable de instancia o miembro de datos) para su nombre. Dependiendo del detalle del diagrama, la notacin de un atributo puede mostrar el nombre, el tipo y el valor predeterminado de un atributo (la sintaxis del UML es visibilidad nombre: tipo = valor por omisin, donde la visibilidad es igual que la de las Operaciones las cuales se describirn en la seccin siguiente). Por lo tanto, cul es la diferencia entre un atributo y una asociacin? Desde la perspectiva conceptual, no hay diferencia; un atributo slo lleva consigo otro tipo de notacin, la cual puede servir si se estima conveniente. Los atributos siempre son de valor nico. Por lo general, los diagramas no indican si los atributos son opcionales u obligatorios (aunque, hablando estrictamente, deberan indicado). La diferencia se da en los niveles de especificacin y de implementacin. Los atributos implican navegabilidad slo del tipo al atributo. Es ms, queda implcito que el tipo contiene nicamente su propia copia del objeto de atributo, lo que implica que cualquier tipo que se emplee como atributo tendr un valor ms que una semntica de referencia. Hablar sobre el valor y los tipos referenciales ms adelante. Por el momento, lo mejor es considerar que los atributos son clases simples y pequeas, tales como cadenas, fechas, objetos de moneda y valores no objeto, como int y real.

OPERACIONES Las operaciones son los procesos que una clase sabe llevar a cabo. Evidentemente, corresponden a los mtodos sobre una clase. En el nivel de especificacin, las operaciones corresponden a los mtodos pblicos sobre un tipo. En general, no se muestran aquellas

operaciones que simplemente manipulan atributos, ya que por lo comn, se pueden inferir. Sin embargo, tal vez sea necesario indicar si un atributo dado es de slo lectura o est inmutable congelado (esto es, que su valor nunca cambia). En el modelo de implementacin, se podran mostrar tambin las operaciones privadas y protegidas. La sintaxis del UML completa para las operaciones es Visibilidad nombre (lista-de-parmetros) : {cadena-de-propiedades} . Donde
y y y y y

expresin-tipo-de-dato-a-regresar

visibilidad es + (public), # (protected), o- (private) nombre es una cadena de caracteres (string) lista-de-parmetros contiene argumentos (opcionales) cuya sintaxis, es la misma que la de los atributos expresin-tipo-de-dato-a-regresar es una especificacin opcional dependiente del lenguaje cadena-de-propiedades indica valores de propiedad que se aplican a la operacin dada

Un ejemplo de operacin sera: + ItimaCantidadDe (valorTipoFenmeno) : Cantidad Dentro de los modelos conceptuales, las operaciones no deben tratar de especificar la interfaz de una clase. En lugar de ello, debern indicar las principales responsabilidades de dicha clase, usando tal vez un par de palabras que sinteticen una responsabilidad de CRC.

TARJETAS DE CRC A fines de la dcada de 1980, uno de los centros ms grandes de tecnologa de objetos era el laboratorio de investigacin de Tektronix, en Portland, Oregon, Estados Unidos. Este laboratorio tena algunos de los principales usuarios de Smalltalk y muchas de las ideas clave de la tecnologa de objetos se desarrollaron all. Dos de sus programadores renombrados de Smalltalk eran Ward Cunningham y Kent Beck. Tanto Cunningham como Beck estaban y siguen preocupados por cmo ensearlos profundos conocimientos de Smalltalk que haban logrado. De esta pregunta sobre cmo ensear objetos surgi la sencilla tcnica de las tarjetas de Clase-Responsabilidad-Colaboracin (CRC). En lugar de utilizar diagramas para desarrollar modelos, como lo hacan la mayora de los metodlogos, Cunningham y Beck representaron las clases en tarjetas 4 x 6 [pulgadas]. Y en lugar de indicar atributos y mtodos en las tarjetas, escribieron responsabilidades. Ahora bien, qu es una responsabilidad? En realidad es una descripcin de alto nivel del propsito de una clase. La idea es tratar de eliminar la descripcin de pedazos de datos y procesos y, en cambio, captar el propsito de la clase en unas cuantas frases. El que se haya seleccionado una tarjeta es deliberado. No se permite escribir ms de lo que cabe en una tarjeta (vase la figura de Tarjeta de Clase-Responsabilidad-Colaboracin (CRC) ).

Nombre de la Clase : Pedido Responsabilidad Colaboracin Revisa si hay elementos en Lnea de existencia pedido Determina precio Lnea de pedido Revisa si el pago es vlido Cliente Despacha a la direccin de entrega
Figura de Tarjeta de Clase-Responsabilidad-Colaboracin (CRC)

La segunda C se refiere a los colaboradores. Con cada responsabilidad se indica culesson las otras clases con las que se tiene que trabajar para cumplida. Esto da cierta idea sobre los vnculos entre las clases, siempre a alto nivel. Uno de los principales beneficios de las tarjetas de CRC es que alientan la disertacin animada entre los desarrolladores. Son especialmente eficaces cuando se est en medio de un caso de uso para ver cmo lo van a implementar las clases. Los desarrolladores escogen tarjetas a medida que cada clase colabora en el caso de uso. Conforme se van formando ideas sob las re responsabilidades, se pueden escribir en las tarjetas. Es importante pensar en las responsabilidades, ya que evita pensar en las clases como simples depositarias de datos, y ayuda a que el equipo se centre en comprender el comportamiento de alto niv de cada clase. el Un error comn que veo que comete la gente es generar largas listas de responsabilidades de bajo nivel. Este procedimiento es completamente fallido. Las responsabilidades deben caber sin dificultad en una tarjeta. Yo cuestionara cualquier tarjeta que tenga ms de tres responsabilidades. Plantese la pregunta de si se deber dividir la clase y si las responsabilidades se podran indicar mejor integrndolas en enunciados de un mayor nivel. CUANDO USAR LAS TARJETAS CRC Algunos consideran maravillosas las tarjetas de CRC; en cambio, a otros, esta tcnica los deja indiferentes. Yo considero definitivamente que se deberan probar, a fin de saber si al equipo de trabajo le gusta trabajar con ellas. Se deben usar, en particular, si el equipo se ha empantanado en demasiados detalles o si parecen identificar clases apelmazadas y carentes de definiciones claras. Se pueden emplear diagramas de clase y diagramas de interacciones y para captar y formalizar los resultados del modelado CRC en un diseo con notacin de UML. Asegrese de que cada clase en su diagrama de clase tiene un enunciado de sus responsabilidades. Con frecuencia encuentro til hacer la distincin entre aquellas operaciones que cambian el estado de una clase y aquellas que no lo hacen. Una consulta es una operacin que obtiene un valor de una clase sin que cambie el estado observable de tal clase. El estado observable de un objeto es el estado que se puede determinar a partir de sus consultas asociadas. Considrese un objeto de Cuenta que calcula su balance a partir de una lista de entradas. Para mejorar el desempeo, Cuenta puede poner en un campo cach el resultado del clculo del

balance, para consultas futuras. Por tanto, si el cach est vaco, la primera vez que se llama a la operacin "balance", pondr el resultado en el campo cach. La operacin "balance" cambia as el estado real del objeto Cuenta, pero no su estado observable, pues todas las consultas devuelven el mismo valor, est o no lleno el campo cach. Las operaciones que s cambian el estado observable de un objeto se llaman modificadores. Considero til tener perfectamente clara la diferencia entre consultas y modificadores. Las consultas se pueden ejecutar en cualquier orden, pero la secuencia de los modificadores es ms importante. Yo tengo como poltica evitar que los modificadores devuelvan valores, con el fin de mantenerlos separados. Otros trminos que algunas veces se presentan son: mtodos de obtencin y mtodos de establecimiento. El mtodo de obtencin (getting) es un mtodo que devuelve el valor de un campo (sin hacer nada ms). El mtodo de establecimiento (setting) pone un valor en un campo (y nada ms). Desde afuera, el cliente no debe poder saber si una consulta es un mtodo de obtencin ni si un modificador es un mtodo de establecimiento. El conocimiento sobre los mtodos de obtencin y establecimiento est contenido completamente dentro de la clase. Otra distincin es la que se da entre operacin y mtodo. Una operacin es algo que se invoca sobre un objeto (la llamada de procedimiento), mientras que unmtodo es el cuerpo del procedimiento. Los dos son diferentes cuando se tiene polimorfismo. Si se tiene un supertipo con tres subtipos, cada uno de los cuales suplanta la operacin "foo" del supertipo, entonces lo que hay es una operacin y cuatro mtodos que la implementan. Es muy comn que operacin y mtodo se empleen indistintamente, pero hay veces en que es necesario precisar la diferencia. En algunas ocasiones, la gente distingue entre una y otro mediante los trminos llamada a un mtodo, o declaracin de mtodo (en lugar de operacin), y cuerpo del mtodo.

Los lenguajes tienen sus propias convenciones para los nombres. En C ++, las operaciones se llaman funciones miembro; En Smalltalk, operaciones de mtodos. C ++ tambin emplea el trmino miembros de una clase para denominar las operaciones y mtodos de una clase.
GENERALIZACION Un ejemplo caracterstico de generalizacin comprende al personal y las Corporaciones clientes de una empresa. Unos y otros tienen diferencias, pero tambin muchas similitudes. Las similitudes se pueden colocar en una clase general Cliente (elsupertipo ) con los subtipos siguientes: Cliente personal y Cliente corporativo. Este fenmeno tambin est sujeto a diversas interpretaciones, segn el nivel de modelado. Por ejemplo, conceptualmente, podemos decir que el Cliente corporativo es un subtipo de Cliente, si todas las instancias de Cliente corporativo, tambin son, por definicin, instancias de Cliente. Entonces, un Cliente corporativo es un tipo especial de Cliente. El concepto clave es que todo lo que digamos de un Cliente (asociaciones, atributos, operaciones) tambin vale para un Cliente corporativo.

En un modelo de especificacin, la generalizacin significa que la interfaz del subtipo debe incluir todos los elementos de la interfaz del supertipo. Se dice, entonces, que la interfaz del subtipo se conforma con la interfaz del supertipo. Otra manera de considerar esto involucra el principio de la sustituibilidad. Yo debo poder sustituir a un Cliente corporativo con cualquier cdigo que requiera un Cliente y todo debe operar sin problemas. En esencia, esto significa que, si escribo un cdigo suponiendo que tengo un Cliente, puedo entonces usar con toda libertad cualquier subtipo de Cliente. El Cliente corporativo puede responder a ciertos comandos de manera diferente a otro Cliente (por el principio del polimorfismo), pero el invocador no debe preocuparse por la diferencia. La generalizacin desde la perspectiva de implementacin se asocia con la herencia en los lenguajes de programacin. La subclase hereda todos los mtodos y campos de la superclase y puede suplantarlos. El punto clave aqu es la diferencia entre generalizacin desde la perspectiva de la especificacin (subtipificacin o herencia de interfaces) y desde la perspectiva de la implementacin (subclasificacin o herencia de implementaciones). La subclasificacin (formacin de subclases) es una manera de implementar la subtipificacin. La subtipificacin (formacin de subtipos) tambin se puede implementar mediante delegacin. En el caso de estas dos formas de generalizacin, se deber asegurar siempre que tambin tenga validez la generalizacin conceptual. He encontrado que, si no se hace lo anterior, se puede uno ver en problemas, debido a que la generalizacin no es estable cuando hay necesidad de efectuar cambios posteriores. En algunas ocasiones aparecen casos en los que un subtipo tiene la misma interfaz que el super tipo, pero el subtipo implementa sus operaciones de modo diferente. Si ste es el caso, se podra decidir no mostrar el subtipo en el diagrama de perspectiva de especificacin. As lo hago con frecuencia si para los usuarios de la clase es interesante la existencia de los tipos, pero no lo hago cuando los subtipos varan nicamente debido a razones internas de implementacin. REGLAS DE RESTRINCION Una buena parte de lo que se hace cuando se dibuja un diagrama de clase es indicar las condiciones limitantes o restricciones. La Figura de Diagrama de clase con navegabilidades indica que un Pedido nicamente puede ser colocado por un solo Cliente. El diagrama implica tambin que Artculos de lnea se considera por separado: digamos 40 adminculos de color marrn, 40 adminculos azules y 40 adminculos rojos, y no 40 artefactos rojos, azules y marrones. El diagrama dice, adems, que los Clientes corporativos tienen lmites de crdito, pero que los Clientes personales no los tienen. Los artificios bsicos de la asociacin, el atributo y la generalizacin, colaboran de manera significativa con la especificacin de condiciones importantes, pero no pueden indicarlas todas. Estas restricciones an necesitan ser captadas; el diagrama de clase es un lugar adecuado para hacerlo.

El UML no define una sintaxis estricta para describir las restricciones, aparte de ponerlas entre llaves ({ }). Yo prefiero escribir en lenguaje informal, para simplificar su lectura. Puede usarse tambin un enunciado ms formal, como un clculo de predicados o alguna derivada. Otra alternativa es escribir un fragmento de cdigo de programacin. Idealmente, las reglas se deberan implementar como afirmaciones en el lenguaje de programacin. stas se corresponden con el concepto de invariantes del Diseo por contrato En lo personal, soy partidario de crear un mtodo revisa invariante e invocarlo desde algn cdigo de depuracin que ayude a comprobar los invariantes. DISEO POR CONTRATO El diseo por contrato es una tcnica diseada por Bertrand Meyer. Esta tcnica es una caracterstica central del lenguaje Eiffel, que l desarroll. Sin embargo, el Diseo por contrato no es especfico de Eiffel; es una tcnica valiosa que se puede usar con cualquier lenguaje de programacin. En el corazn del Diseo por contrato se encuentra la afirmacin. Unaafirmacin es un enunciado Booleano que nunca debe ser falso y, por tanto, slo lo ser debido a una falla. Por lo comn, las afirmaciones se comprueban slo durante la depuracin y no durante la ejecucin en produccin. De hecho, un programa nunca debe su poner que se estn comprobando las afirmaciones. El Diseo por contrato se vale de tres tipos de afirmaciones: poscondiciones, precondiciones e invariantes. Las precondiciones y las poscondiciones se aplican a las operaciones. Una poscondicin es un enunciado sobre cmo debera verse el mundo despus de la ejecucin de una operacin. Por ejemplo, si definimos la operacin "cuadrado" sobre un nmero, la poscondicin adoptara la forma de resultado = ste * ste, donde resultado es el producto y ste es el objeto sobre el cual se invoc la operacin. La poscondicin es una forma til de decir qu es lo que hacemos, sin decir cmo lo hacemos; en otras palabras, de separar la interfaz de la implementacin. La precondicin es un enunciado de cmo esperamos encontrar el mundo, antes de ejecutar una operacin. Podemos definir una precondicin para la operacin"cuadrado" de ste > = 0. Tal precondicin, dice que es un error invocar a "cuadrado" sobre un nmero negativo, y que las consecuencias de hacerlo son indefinidas. A primera vista, sta no parece ser una buena idea, pues deberamos poner una comprobacin en alguna parte para garantizar que se invoque correctamente a "cuadrado". La cuestin importante es quien es responsable de hacerlo. La precondicin hace explcito que quien invoca es el responsable de la comprobacin. Sin este enunciado explcito de responsabilidades, podemos tener muy poca comprobacin (pues ambas partes suponen que la otra es la responsable) o tenerla en demasa (cuando ambas partes lo hacen). Demasiada comprobacin es mala, ya que provoca que se duplique muchas veces el cdigo de comprobacin, lo cual puede complicar de manera importante un programa. El ser explcito sobre quin es el responsable contribuye a reducir esta complejidad. Se reduce el peligro de que el invocador olvide comprobar por el hecho de que, por lo general, las afirmaciones se comprueban durante las pruebas y la depuracin.

A partir de estas definiciones de precondicin y poscondicin, podemos ver una definicin slida del trmino excepcin, que ocurre cuando se invoca una operacin estando satisfecha su precondicin y, sin embargo, no puede regresar con su poscondicin satisfecha. Una invariante es una afirmacin acerca de una clase. Por ejemplo, la clase Cuenta puede tener una invariante que diga que balance = sum(entradas.cantidad()) La invariante "siempre" es verdadera para todas las instancias de la clase. En este contexto," iempre " s significa "siempre que el objeto est disponible para que se invoque una operacin sob ella". re En esencia, lo anterior significa que la invariante se agrega a las precondiciones y poscondiciones asociadas a todas las operaciones pblicas de la clase dada. La invariante puede volverse falsa durante la ejecucin de un mtodo pero debe habers restablecido a e verdadera para el momento en que cualquier otro objeto pueda hacerle algo al receptor. Las afirmaciones pueden desempear un papel nico en la subclasificacin. Uno de los peligros del polimorfismo es que se podran redefinir las operaciones de una subclase, de tal modo que fueran inconsistentes con las operaciones de la superclase. Las afirmaciones impiden hacer esto. Las invariantes y poscondiciones de una clase deben aplicarse a todas las subclases. Las subclases pueden elegir el refuerzo de estas afirmaciones, pero no pueden debilitadas. La precondicin, por otra parte, no puede reforzarse, aunque s debilitarse. Esto parecer extrao a primera vista, pero es importante para permitir vnculos dinmicos. Siempre debera ser posible tratar un objeto de subclase como si fuera una instancia de su superclase (de acuerdo con el principio de la sustituibilidad). Si una subclase retuerza su precondicin, entonces podra fallar una operacin de superclase, cuando se aplicara a la subclase. En esencia, las afirmaciones slo pueden aumentar las responsabilidades de la subclase. Las precondiciones son un enunciado para trasladar una responsabilidad al invocador; se incrementan las responsabilidades de una clase cuando se debilita una precondicin. En la prctica, todo esto permite un mucho mejor control de la subclasificacin y ayuda a asegurar que las subclases se comporten de manera adecuada. Idealmente, las afirmaciones se deben incluir en el cdigo, como parte de la definicin de la interfaz. Los compiladores deben poder encender la comprobacin por afirmaciones durante las depuraciones y apagada durante la operacin en produccin. Se pueden manejar varias etapas de comprobacin de afirmaciones. Las precondiciones a menudo ofrecen las mejores posibilidades de atrapar errores con la menor cantidad de sobrecarga de proceso. CUANDO UTILIZAR EL DISEO POR CONTRADO El Diseo por contrato es una tcnica valiosa que siempre se debe emplear cuando se programa. Es particularmente til para la construccin de interfaces claras. Slo Eiffel maneja afirmaciones como parte de su lenguaje, pero desafortunadamente Eiffel no es un lenguaje de amplia difusin. La adicin de mecanismos a C ++ y Smalltalk que manejen algunas afirmaciones es directa. Es mucho ms engorroso hacer algo similar en Java, pero es posible.

El UML no habla mucho acerca de las afirmaciones, pero se pueden usar sin problemas. Las invariantes son equivalentes a las reglas de condicin en los diagramas de clase y se debern usar tanto como sea Posible. Las precondiciones y pos condiciones de operacin se deben documentar con las definiciones de las operaciones. CUANDO EMPLEAR LOS DIAGRAMA DE CLASES Los diagramas de clase son la columna vertebral de casi todos los mtodos OO, por lo cual usted descubrir que se emplean todo el tiempo. Este captulo ha abarcado los conceptos bsicos; el captulo siguiente, analizar muchos de los conceptos ms avanzados. El problema con los diagramas de clase es que son tan ricos que pueden resultar abrumadores. A continuacin, damos algunos consejos breves
y

No trate de usar todas las anotaciones a su disposicin. Comience con el material sencillo de este captulo: clases, asociaciones, atributos y generalizacin. Introduzca otras anotaciones ms avanzadas slo cuando las necesite. Ajuste la perspectiva desde la cual se dibujan los modelos a la etapa del proyecto. o Si se est en la etapa del anlisis, dibuje modelos conceptuales. o Cuando se trabaje con software, cntrese en los modelos de especificacin. o Dibuje modelos de implementacin slo cuando se est ilustrando una tcnica de implementacin en particular. No dibuje modelos para todo; por el contrario, cntrese en las reas clave. Es mejor usar y mantener al da unos cuantos diseos que tener muchos modelos olvidados y obsoletos.

El principal peligro con los diagramas de clase es que se puede quedar empantanado muy pronto en los detalles de la implementacin. Para contrarrestar esto, cntrese en las perspectivas conceptual y de especificacin. Si cae en estos problemas, encontrar muy tiles las tarjetas de CRC

También podría gustarte