Clases del Diseño

Clases del Diseño
Información sobre la plantilla
Formato grafico de una clase.JPG
Concepto:Formato gráfico de una clase en UML.

Clases del Diseño . Una clase es una descripción o abstracción lógica de un conjunto de objetos que comparten los mismos atributos, operaciones, relaciones y semántica.

Clases en UML

Una clase de UML se representa con un rectángulo dividido en tres secciones. De las tres secciones que conforman la clase UML, la sección superior o primera sección es empleada para indicar el nombre de la clase; la segunda sección o intermedia es utilizada para mostrar los atributos y la ultima es empleada para las responsabilidades de la clase.

  • Atributos en la clase UML

Los atributos de una clase no puedan ser accedidos directamente, por lo que su visibilidad debería siempre ser privada o protegida para cumplir con el encapsulamiento. Gráficamente la visibilidad privada se muestra con un signo menos (-) delante del atributo en cuestión, la visibilidad protegida se muestra con un signo de número (#) y la pública con un signo mas (+), aunque una descripción visual alternativa es empleada en algunas herramientas de modelado como Rational Rose . Para cada atributo de la clase se puede especificar su visibilidad, tipo de dato y valor inicial en caso de existir y la sintaxis completa queda de la siguiente forma: Visibilidad + Nombre + TipoDato + Valor Inicial.

  • Métodos en la clase UML.

Otro elemento que se modela relativo a las clases en UML es el comportamiento, el mismo se captura como métodos que quedan documentados en la tercera sección de la clase UML. La sintaxis para documentar los métodos de una clase es el siguiente: Visibilidad + Nombre + Lista Argumentos + Tipo de Retorno.

La visibilidad empleada en atributos y operaciones ayuda a mantener el encapsulamiento, permitiendo tener soluciones más modulares, fáciles de mantener y menos acopladas.

Estereotipos y Representación Gráfica

Formas de representar una clase estereotipada como entidad (<<entity>>). A) En forma de Icono, B) Decoración en la sección del nombre de la clase, C) Etiqueta textual

Dependiendo del nivel que se este modelando, ya sea Análisis y Diseño o Implementación, los diferentes elementos que se tienen en un modelo, pueden “marcarse” para indicar que cumplen con un objetivo determinado. Dichas marcas pueden ser aplicadas a paquetes, clases, atributos de una clase, operaciones de una clase y relaciones entre ellas. Las marcas son muy útiles para tener una idea a simple vista del propósito que tiene un elemento del modelo en un diagrama. Por ejemplo, una operación podría marcarse como <<constructor>>, para indicar que es el constructor de la clase y no cualquier otra operación. Un atributo podría marcarse como <<identifier>> para indicar que en materia de persistencia, es el identificador de la clase, y no un atributo cualquiera. Estas “marcas” son conocidas como estereotipos, y pueden estar acompañadas de una representación gráfica, que resulta un factor clave para su comprensión por parte de los especialistas. Existen herramientas de modelado que no tienen una representación gráfica para ciertos estereotipos aunque estos sean muy comunes, y por lo tanto la marca solamente la permiten hacer de forma textual. Aunque resulta más cómodo poder contar con un icono que permita identificar el propósito de una clase, es igualmente válido, expresar esta marca en forma textual.

Relaciones entre clases

En el diseño orientado a objetos existe un principio denominado alta cohesión, que establece que debe existir una fuerte relación entre las responsabilidades (métodos) de una clase. Siguiendo este principio se debe evitar que una sola clase sepa “hacerlo todo”, y tratar de que la clase se dedique a responsabilidades concretas muy fuertemente relacionadas entre sí, y todo lo que no pueda completar por si misma, deberá delegarlo en alguna de las clases restantes existentes en la solución. Por ejemplo no se puede tener en una sola clase métodos para la implementación de un algoritmo de búsqueda en textos, conjuntamente con la recuperación, carga y almacenamiento en ficheros y la visualización de resultados. Cada una de las áreas, visualización, recuperación, y el algoritmo en sí, puede quedar encapsulada en objetos distintos, que se dedican a funciones específicas acotadas en cierto alcance, y que pueden interactuar unos con otros para completar su funcionamiento.

Una solución orientada a objetos por naturaleza está formada por objetos que interactúan y colaboran unos con otros, de tal forma que pueda completarse todo el funcionamiento especificado en los requisitos. La forma en que un objeto puede colaborar con otro es a través de relaciones que se establecen entre ellos. Estas relaciones son diversas y UML cuenta con distintas formas para modelarlas.

Relación de Dependencia o “Dependency”

En una operación de la clase viajero, podría solicitársele el equipaje, y el viajero como resultado del método, retorna una instancia de la clase Equipaje, ya esta situación es suficiente para indicar una relación de tipo dependency entre Viajero y Equipaje

Es una relación que se establece entre una clase A y una B, cuando se cumple que: 1. La clase A tiene que crear en tiempo de ejecución instancias de la clase B y luego de emplearlas, las libera. Es decir, las emplea momentáneamente, no tiene una referencia a la clase B, sino que crea un objeto cuando lo requiere, por ejemplo como una variable local a un procedimiento o función. 2. La clase A recibe como parámetro de alguna de sus operaciones una instancia de la clase B. 3. La clase A retorna como resultado de alguna de sus operaciones, una instancia de la clase B.

En los casos anteriores se trata de una dependencia que en el tiempo es volátil, no existe una referencia constante desde los objetos de la clase A a un objeto concreto de la clase B, sino que eventualmente, se reserva memoria para estos y se emplean o retornan de acuerdo a la necesidad.

La relación de dependencia se representa gráficamente como una saeta discontinua entre las clases. Dirigida desde la clase cliente, hacia la clase proveedora, es decir, desde la clase que necesita hacia la clase que es empleada.


Relación de Asociación o “Asociation”

Representación de una relación de Asociación entre dos clases

Es un tipo de relación en la cual, a diferencia de la anterior, existe una dependencia entre las clases que es permanente en el tiempo, y tiene una implicación directa en la estructura estática de la clase. En concreto, una forma simple de saber que se está en presencia de una asociación es cuando la clase A, una vez implementada (código fuente), va a tener un atributo de tipo B, es decir una referencia a un objeto de la clase B. Por eso se dice que es una dependencia permanente en el tiempo.

Si se está evaluando la posibilidad de que exista una asociación entre la clase A y la clase B, es porque la clase A, de algún modo es dependiente, necesita de la clase B. Hasta este punto podría ser una relación de Dependencia (dependency) simplemente, pero para tomar la decisión debe tener en cuenta si la necesidad persiste, permanece en el tiempo, por ejemplo se requiere tener referencia a uno o varios objetos de la clase B todo el tiempo como sucede con un bicicleta y sus ruedas, con una Persona y su Carnet de Identidad, o por ejemplo que en cada operación de la clase A se emplea una instancia de la clase B que se requiere que esté disponible todo el tiempo.

La relación de asociación se representa gráficamente con una saeta continua.

Por ejemplo entre una clase Viajero y una clase Pasaporte (como se muestra en la figura) una vez implementadas las clases, una relación de asociación tiene una implicación bien delimitada. En el código de la clase Viajero existirá la implicación siguiente:


class Viajero {
private String nombre;
private char sexo;
private Pasaporte pass;
...
}
Durante el Análisis no resulta significativo distinguir entre una relación de asociación, o una relación de dependencia, ya que todas las relaciones reconocidas en este punto del desarrollo de software, sufrirán un refinamiento en diseño, por lo que aún se tiene la oportunidad para establecer correctamente cuál relación en concreto es la que se necesita. Usualmente se emplean relaciones de asociación y no de dependencia durante el análisis.

Pueden existir casos en que dos clases pueden tener entre ellas más de una relación.

Relación de Agregación o “Agregation”

Representación de una relación de Agregación

Es un tipo de relación en la que se puede identificar que existe un concepto que está formado por partes. Se le conoce como relación todo-partes, es decir, existe una o varias partes que se unen para formar un todo. Por ejemplo, una bicicleta está formada por varias piezas o partes, como pueden ser ruedas, timón, entre otras. Igualmente un aula esta formada por puertas, ventanas, sillas, mesas. En la relación bicicleta – rueda, o aula – puerta, parece natural que existe una semántica “todo-partes”, donde las partes se unen para conformar el todo. Sólo si es natural el hecho de que un concepto A “está formado por” un concepto B, entonces se modela al menos una relación de agregación. Se dice al menos una relación de agregación porque hasta ese punto, podría ser también una relación de composición. Una relación de agregación se representa visualmente con un rombo vacío que se dibuja en el extremo de la relación que se corresponde con el “todo”.


Relación de Composición o “Composition”

Representación de una relación de Composición

Una relación de composición es una agregación, en la que la “parte”, pertenece exclusivamente a su correspondiente “todo”. Es decir, no se puede compartir una parte por varios todos.

Por ejemplo, la puerta principal de nuestra casa, no pertenece a la vez a nuestra casa y a la de algún vecino. Sin embargo la puerta que divide a dos habitaciones de una casa, es compartida por ambas habitaciones. En el primer caso podemos decir que una casa está formada por ventanas, habitaciones, y una Puerta Principal, es decir existe una relación “todo-partes”, hasta este punto podría ser una agregación. Al analizar la relación se encuentra que la puerta principal es únicamente de una casa, es decir no se comparte por varias casas, eso hace determinar que la relación entre Casa y Puerta principal, es una composición y no una agregación. Adicionalmente se encuentra que cuando existe una relación de composición, no es que la “parte” exista, si no está relacionada al “todo”, en materia de memoria, no se puede tener creada una instancia de una parte aislada, si el “todo” dejó de existir, es decir, al liberar la memoria del “todo”, por ejemplo a partir de la llamada al destructor de la clase, esta deberá encargarse de destruir a todas las partes, cuyas relaciones con el “todo” eran de composición. Una llamada al destructor de la clase Casa, debe internamente llamar al destructor de la instancia de Puerta Principal asociada.

La relación de composición se representa gráficamente similar a la agregación pero con el rombo lleno.

Relación de Herencia o “Hierarchy”

Representación gráfica de una relación de herencia. La relación debe ser interpretada en el sentido de la saeta, “Perro es un Animal”

La herencia, es una relación en la que existe un elemento generalizador y uno especializado, razón por la cual se le conoce también como Generalización-Especialización. La señal más inminente de que se está frente a una relación de Herencia, entre la clase A y la Clase B, es cuando se puede decir naturalmente que la clase A “es un” B. Por ejemplo: Perro “es un” Animal.

En ocasiones, los programadores, para reutilizar comportamiento (operaciones) o estado (atributos), establecen relaciones de herencia que son antinaturales, y esto siempre será algo que se debe evitar, porque es más importante la simplicidad, legibilidad y facilidad de mantenimiento del código que el ahorro de un par de líneas de este.

Por ejemplo, una bicicleta tiene un código de 11 dígitos, que permite identificarla, es decir es llave primaria, además la bicicleta tiene un color. Una persona por su parte también tiene un color y coincidentemente un código de 11 dígitos que la identifica. Aunque existe semejanza entre persona y bicicleta, es falso decir que una Persona “es una” Bicicleta y en cuanto a concepto no es natural la relación de herencia entre ellos. La relación de herencia se representa gráficamente con una saeta con la punta triangular que se traza desde el extremo especializado hacia el extremo generalizador.

Atributos de una relación entre clases

Las relaciones entre las clases pueden ser enriquecidas a partir de atributos que son relativos a un extremo u otro de la relación, y que permiten capturar verdaderamente la semántica existente en un dominio determinado. Entre ellos podemos encontrar la Cardinalidad, Navegabilidad, Nombre de Asociación y Nombre de Rol.

Cardinalidad

Uno de los atributos que tiene la relación entre objetos de dos clases diferentes es la cardinalidad, que establece “qué cantidad de objetos de una clase está relacionado con qué cantidad de objetos de la otra clase”. La cardinalidad es relativa a cada extremo de la relación. Por ejemplo:

  • Una bicicleta tiene 2 ruedas
  • Un grupo tiene muchos alumnos
  • Una Persona tiene solamente 1 corazón.

Ejemplificando en un caso, en el que una computadora puede ser compartida por varios usuarios y cada usuario puede tener acceso solamente a una computadora. Es necesario conocer por separado que una persona solamente puede ser usuario en una computadora, mientras que una computadora puede ser empleada por varios usuarios. O sea que cada extremo debe poderse examinar independientemente, y capturar la cardinalidad del extremo opuesto en ese examen. Para determinar la cardinalidad del extremo B en una relación entre una clase A y una clase B, hay que situarse en el extremo opuesto (A), y se efectúa la pregunta ¿Cuántos “B” pueden estar asociados a un “A”? Entre la clase Computadora y la clase Persona, para conocer la cardinalidad del extremo Computadora, ha que situarse en el extremo Persona y se realiza la pregunta: ¿En cuántas computadoras puede una persona ser usuario? Respuesta (dado el ejemplo) -Solamente en 1. Luego hay que situarse en el extremo Computadora y se vuelve a efectuar la pregunta, ahora relativa a ese extremo: ¿Cuántas personas pueden ser usuarios de una computadora? Respuesta (dado el ejemplo) - Muchas.

Representación gráfica de la cardinalidad o multiplicidad en una relación

En cada extremo de la asociación se incorpora un valor que corresponde con un rango. Los valores posibles de rango a emplear son:

  • 1 : Uno; Empleado para exactamente una instancia (como el ejemplo de persona-computadora) Esta multiplicidad obliga a que exista la referencia al extremo opuesto. Traducido al ejemplo anterior, el extremo 1 entre Persona – Computadora, obliga a que no pueda haber una persona que no tenga asignada computadora.
  • 0..1 : Cero o uno; Se emplea cuando la cantidad máxima es 1 pero podría ser cero. Por ejemplo si las computadoras no alcanzan y por tanto pudiera haber personas que no son usuarios en ninguna computadora.
    •  : Muchos; Empleado cuando pueden ser muchas instancias, por ejemplo el extremo Persona en la relación Persona – Computadora. Algunas herramientas, emplean la letra ENE (n) para representar esta multiplicidad de “muchos”.
  • 0..*: Cero o Muchos; Cuando pueden ser muchos o ningún objeto.

Incluso podría indicarse un número entero cuando se conoce por ejemplo entre Bicicleta y Rueda el extremo rueda tiene multiplicidad 2. En el flujo de trabajo de Análisis, identificar la multiplicidad exacta entre los objetos no es un elemento obligatorio, es decir, si se puede determinar a primera vista se hace, en caso contrario, se deja para el refinamiento en el diseño.

Navegabilidad

Asociación unidireccional entre Persona y Computadora. La saeta indica que solamente hay visibilidad desde el extremo Persona hacia el extremo Computadora
Asociación Navegable entre Persona y Computadora. La visibilidad es en ambos sentidos


La navegabilidad es un atributo que, al igual que la multiplicidad, es relativo a las asociaciones. Se dice que una asociación es navegable cuando se puede acceder desde cada extremo al extremo opuesto. En caso contrario, la asociación no es navegable, se dice que es unidireccional o navegable en un solo sentido. Esta última se da cuando desde un extremo se puede “ver” al extremo opuesto, mientras que desde el otro no.

Generalmente es necesario desde un objeto, acceder a las propiedades o comportamiento de otro u otros objetos con los cuales tiene relación.

El siguiente fragmento de código fuente bien podría ser de la clase Persona:

this.computadora.getCodigo();

Desde un objeto de una clase (representado por la variable this) se ejecuta la operación “getCodigo()” de otro objeto con el cual el primero está asociado, denominado “computadora”.

En este caso se dice que la Computadora asociada a una persona es “visible” desde la clase Persona. Hasta ese punto se ve que la clase Persona “conoce”, puede “ver”, y por tanto acceder a propiedades y métodos de la clase Computadora, lo cual tiene la implicación de que al menos exista una asociación navegable en el sentido Persona à Computadora.

Si además, desde una computadora se puede “conocer”, “ver”, “tener acceso” a la lista de usuarios correspondientes, entonces eso implicaría que la relación Persona – Computadora, debe ser navegable, es decir existir visibilidad en ambos sentidos.

O sea desde la clase Computadora se debe tener acceso a las personas asociadas, lo cual implica que la relación debe ser navegable, hay visibilidad en ambos sentidos. Bajo estas condiciones se podría, desde la clase Computadora, tener un código parecido al siguiente:

this.usuarios.getCount();

Nombre de asociación y nombre de Rol

La descripción de una relación entre dos clases puede ser enriquecida si se adiciona información relacionada a qué hace una clase con respecto a la otra, o qué Rol juega un extremo con respecto al otro.

Por ejemplo, se tienen dos clases, una clase Persona y una clase Almacén, sin nombre de Asociación ni nombre de Rol. Si el diagrama no es suficiente y el mismo presenta ambigüedad o falta información, es porque no se ha dicho lo suficiente del mismo.

Relación Persona-Almacén sin nombre de asociación ni Nombre de Rol

Si se realiza el mismo diagrama pero adicionándole la información sobre ¿Qué le hace la Persona al Almacén? Con esto se conoce la naturaleza de la relación más fácilmente. (Diagrama con Nombre de asociación)

Relación Persona-Almacén con Nombre de asociación

Si se repite el diagrama pero ahora la información adicionada es relativa a ¿Qué rol juega la persona en la relación con Almacén? Igualmente el modelo es más claro y comprensible con el nombre de Rol.

Relación Persona-Almacén con Nombre de Rol

En ocasiones es suficiente con emplear uno de los dos elementos (Nombre Asociación o Nombre Rol). Si se dice que la persona juega el rol de “Administrador” del almacén, se hace un poco redundante decir además que lo “administra”. En la mayoría de los casos se puede emplear el nombre de la asociación, aunque en otros, es vital el nombre del Rol, pues el nombre de la asociación da pie a cierta inconsistencia, sobre todo cuando existe más de una asociación entre las mismas clases.

Fuentes

  • JACOBSON, Ivar; RUMBAUGH, James; BOOCH, Grady, “El proceso unificado de desarrollo”.2000. Addison Wesley. capítulos 9 Páginas 205-254.
  • RUMBAUGH, James, JACOBSON, Ivar; BOOCH, Grady, “El lenguaje unificado de modelado. Manual de referencia”.2000. Addison Wesley. Capítulos 8 y 13 Páginas 75-80, 214, 216-218, 175-182 y 330.
  • LARMAN, Craig “UML y patrones” 1999, Prentice Hall Iberoamericana. Capítulos 13, 16, 17, 18, 19, 21, 34 y 35.
  • Bruegge, B. Y Dutoit, A. “Ingeniería de Software Orientado a Objetos”. 2002. Prentice Hall – Pearson Educación. Capítulos 5 y 6. Páginas 146-149, 167-229.
  • GAMMA, E.; HELM, R.; JOHNSON, R. y VLISSIDES, J. “Patrones de diseño”.2000. http//www.vico.org/pages/PatronsDisseny.html.
  • UML y la Modelación de datos.pdf. Whitepaper de Rational Rose.