Modelando con clases
Los diagramas de clase UML son una
de las herramientas más importantes tanto para el análisis de requisitos como
para el diseño de sistemas de software orientados a objetos. Estos diagramas
muestran las clases, sus atributos y operaciones, así como los diversos tipos
de relaciones que existen entre las clases.
¿Qué es el UML?
El lenguaje de modelado unificado
(UML) es un lenguaje gráfico estándar para modelar software orientado a
objetos. Fue desarrollado a mediados de la década de 1990 como un esfuerzo de
colaboración por James Rumbaugh, Grady Booch e Ivar Jacobson, cada uno de los
cuales había desarrollado su propia notación a principios de la década de 1990.
¿Por qué usar un lenguaje de
modelado estándar?
Algunos desarrolladores han tenido
éxito en el desarrollo de pequeños sistemas de software sin el uso de diagramas
u otras características de los lenguajes de modelado. Sin embargo, a medida que
sus sistemas se vuelven cada vez más grandes, a estos desarrolladores les
resulta cada vez más difícil ver el "panorama general" y pueden crear
diseños deficientes y tomar mucho más tiempo en su trabajo.
Historia de la orientación a
objetos: métodos y anotaciones
En la década de 1980, el enfoque
orientado a objetos comenzó a ser ampliamente aceptado en la comunidad del
software como una buena forma de hacer frente a la complejidad del software. En
ese momento, sin embargo, la orientación a los objetos se aplicaba
principalmente a nivel de programación; no hubo orientación para los ingenieros
de software sobre cómo analizar o diseñar sistemas de una manera orientada a
objetos. A medida que las personas continuaron desarrollando software cada vez
más complejo, claramente se necesitaban enfoques sistemáticos para el análisis
y el diseño.
A finales de los años ochenta y
principios de los noventa, aparecieron las primeras metodologías orientadas a
objetos. Cada uno de estos se publicó como un libro y propuso su propia
notación para el modelado.
Fundamentos de los diagramas de
clase UML
Los diagramas de clases describen
los datos encontrados en un sistema de software.
■ Clases, que representan los tipos
de datos en sí.
■ Asociaciones, que muestran cómo
las instancias de clases hacen referencia a instancias de otras clases.
■ Atributos, que son datos simples
encontrados en instancias.
■ Operaciones, que representan las
funciones realizadas por las instancias.
■ Generalizaciones, que se utilizan
para organizar las clases en jerarquías de herencia.
Clases
Una clase se representa como un
cuadro con el nombre de la clase dentro.
Asociación
Se utiliza una asociación para
mostrar cómo las instancias de dos clases se referenciarán entre sí. La
asociación se dibuja como una línea entre las clases.
Asociaciones de etiquetado
Cada asociación se puede etiquetar,
para hacer explícita la naturaleza de la asociación.
Hay dos tipos de etiquetas, nombres
de asociación y nombres de roles.
Analizando y validando asociaciones
Es muy común cometer errores al
crear asociaciones; es particularmente fácil equivocarse en la multiplicidad.
Por lo tanto, debe acostumbrarse a leer cada asociación en ambas direcciones
para verificar que tiene sentido. Lo más importante, siempre debe preguntarse
si una multiplicidad menos restrictiva también podría tener sentido en algunas
circunstancias. Por menos restrictivo, nos referimos al uso de
"muchos" u "opcional" en lugar de "uno" u otro
número específico.
Clases de asociación
En algunas circunstancias, un
atributo que concierne a dos clases asociadas no se puede colocar en ninguna de
las clases.
Asociaciones reflexivas
Es posible que una asociación
conecte una clase consigo misma.
Enlaces como instancias de
asociaciones
De la misma manera que decimos que
un objeto es una instancia de una clase, decimos que un enlace es una instancia
de una asociación. Cada enlace conecta dos objetos, una instancia de cada una
de las dos clases involucradas en la asociación.
Direccionalidad en asociaciones
Las asociaciones y enlaces son por
defecto bidireccionales. Es decir, si un objeto Driver está vinculado a un
objeto Car, entonces el Coche también está implícitamente vinculado a ese
Driver. Si conoce el automóvil, puede averiguar su conductor, o si conoce al
conductor, puede averiguarlo.
generalización
Recordará que se representan con un
pequeño triángulo que apunta a la superclase. Deben seguir la regla isa y
varias otras reglas también. Aquí, presentaremos algunos problemas más a tener
en cuenta al crear generalizaciones.
Evitar generalizaciones
innecesarias
Un error común cometido por los
principiantes es exagerar la generalización.
Manejo de múltiples conjuntos de
generalización
Un conjunto de generalización es un
grupo etiquetado de generalizaciones con una superclase común; La etiqueta
describe los criterios utilizados para especializar la superclase en dos o más
subclases.
Evitar que los objetos cambien de
clase
Otro problema que puede surgir al
crear generalizaciones es evitar la necesidad de que los objetos cambien de
clase. En general, un objeto nunca debería necesitar cambiar de clase. En la
mayoría de los lenguajes de programación, cambiar de clase simplemente no es
posible; por lo tanto, debe destruir completamente el objeto original y crear
una nueva instancia de la segunda clase. Esto es complejo y propenso a errores
porque tiene para copiar todas las variables de instancia y asegurarse de que
todos los enlaces que se conectaron al objeto antiguo ahora se conectan al
nuevo.
diagramas de objetos
Los diagramas de clases nos dicen
qué clases existirán en un sistema dado, pero son bastante abstractas. A veces
puede ser difícil visualizar las relaciones entre los objetos que existirán en
tiempo de ejecución.
Un diagrama de objetos muestra un
ejemplo de configuración de objetos y enlaces que pueden existir en un punto
particular durante la ejecución de un programa.
Probabilidades y extremos sobre
diagramas de objetos
Los diagramas de objeto a veces se
llaman diagramas de instancia. Ha habido una tendencia para algunas personas a
hablar sobre diagramas de objetos cuando se refieren a diagramas de clase. El
término "diagrama de instancia" evita esta confusión a pesar de que
no es UML estándar.
La mayoría de las herramientas para
dibujar diagramas UML no proporcionan facilidades para dibujar diagramas de
objetos. Esto se debe a que los diagramas de clase contienen una vista
abstracta del sistema que es mucho más rica en información y siempre es
necesaria, mientras que los diagramas de objetos se usan con menos frecuencia y
solo para analizar escenarios específicos.
Asociaciones versus
generalizaciones en el contexto de diagramas de objetos
Es un error común para los
principiantes pensar en las generalizaciones como asociaciones especiales. Este
concepto erróneo surge porque tanto las generalizaciones como las asociaciones
conectan las clases en un diagrama de clases.
Sin embargo, las diferencias entre
los dos conceptos son profundas.
■ Una asociación describe una
relación que existirá entre instancias en tiempo de ejecución.
■ Una generalización describe una
relación entre clases en un diagrama de clases.
Agregación
Las agregaciones son asociaciones
especiales que representan relaciones de "parte-todo".
El lado "completo" de la
relación a menudo se denomina ensamblaje o agregado.
Cuándo usar una agregación en lugar
de una asociación ordinaria siempre ha sido una fuente de confusión. Como regla
general, puede marcar una asociación como una agregación si se cumple lo
siguiente:
■ Puede indicar que las partes ‘son
parte de’ el agregado, o que el agregado ‘está compuesto de’ las partes.
■ Cuando algo posee o controla el
agregado, entonces ellos también poseen o controlan las partes.
Una composición es un tipo fuerte
de agregación en la que si se destruye el agregado, también se destruyen las
partes.
Interfaces
Una interfaz es similar a una
clase, excepto que carece de
variables de instancia y métodos
implementados. Normalmente contiene solo métodos abstractos, aunque también
puede contener variables de clase. Podemos decir que una interfaz describe una
parte del comportamiento visible de un conjunto de objetos.
Restricciones, notas y texto
descriptivo Muy a menudo, en un diagrama de clase, desea decir más de lo que la
notación gráfica UML permite fácilmente. Hay tres formas en que puede agregar
información adicional a un diagrama UML:
■ Texto descriptivo y otros
diagramas. Se recomienda encarecidamente insertar sus diagramas en un documento
más grande que describa el sistema de manera más completa. Dicho texto puede
explicar aspectos del sistema utilizando cualquier notación que desee. Es mejor
no repetir lo que se muestra en los diagramas UML, pero puede resaltar y
expandir características importantes, y explicar por qué se tomaron ciertas
decisiones.
■ Notas. A diferencia del texto
descriptivo descrito anteriormente, una nota es un pequeño bloque de texto
incrustado en un diagrama UML. La caja tiene una "esquina doblada".
La nota puede explicar un detalle y actúa como un comentario en un lenguaje de
programación.
■ Restricciones. Una restricción es
como una nota, excepto que está escrita en un lenguaje formal que puede ser
interpretado por una computadora.
Los fundamentos del lenguaje de
restricción de objetos (OCL)
OCL es un lenguaje formal diseñado
para mejorar las capacidades de modelado de UML. Originalmente fue diseñado
exclusivamente para especificar restricciones en modelos UML; la última
versión, sin embargo, también se puede usar para especificar cosas como rutas
de navegación que le permiten formular consultas de información en modelos UML.
Nos centraremos aquí en su uso
original para modelar restricciones, y daremos ejemplos que puede emular para
escribir los tipos más comunes de restricciones. Aunque solo discutiremos su
uso en diagramas de clases, OCL también se puede usar en otros tipos de
diagramas UML donde se requiere la especificación de restricciones. Si desea
obtener más información, puede consultar un libro más avanzado o la
especificación OCL en sí misma, disponible en Object Management Group.
Las declaraciones OCL más simples
se pueden construir a partir de los siguientes elementos:
■ Referencias a nombres de roles,
nombres de asociaciones, atributos y resultados de operaciones.
■ Los valores lógicos verdadero y
falso
■ Operadores lógicos como y, o,
=,>, <o <> (no es igual)
■ Valores de cadena como: 'una
cadena'
■ Enteros y números reales (este
último tiene un punto decimal)
■ Operaciones aritméticas *, /, +,
-
El proceso de desarrollar diagramas
de clase.
Hasta ahora en este capítulo hemos
discutido la sintaxis de los diagramas de clases y hemos planteado algunos
problemas sobre lo que constituye un modelo bueno o malo. Sin embargo, es
posible que se pregunte: ¿por dónde empiezo y qué pasos debo seguir para
asegurarme de construir un modelo efectivo? Esta sección proporciona alguna
orientación sobre este tema.
Diagramas de clase versus diagramas
de relación de entidad Los diseñadores de bases de datos han usado durante
muchos años una notación llamada Diagramas de relación de entidad (ERD).
Esta notación tiene mucho en común
con los diagramas de clase de UML; de hecho, los desarrolladores de OMT, un
predecesor de UML, tomaron muchas ideas de los ERD. En los ERD, las
"entidades" son similares a las clases y
Las "relaciones" son
similares a las asociaciones. Las relaciones se muestran utilizando un símbolo
de diamante grande, que es una de las características que los hace
sustancialmente más voluminosos que los diagramas de clase. También,
Los ERD estándar no muestran
operaciones. Los ERD tradicionales tampoco mostraron herencia, pero los ERD
extendidos (EERD) sí.
Modelos del dominio, versus modelos
del sistema.
Puede crear diagramas de clases u
otros modelos UML en diferentes etapas del proceso de ingeniería de software y
con diferentes propósitos y niveles de detalle.
Una secuencia sugerida de
actividades.
■ Identificar un primer conjunto de
clases candidatas.
■ Comenzando con las clases más
importantes, agregue las asociaciones y atributos que claramente serán
necesarios.
■ Resolver las generalizaciones más
claras.
■ Haga una lista de las principales
responsabilidades de cada clase. Estas son declaraciones simples de funciones
que debe realizar cada clase; los discutiremos a continuación.
Según las responsabilidades, decida
las operaciones específicas que se necesitan.
■ Repita todo el proceso,
examinando el modelo para ver si necesita agregar o eliminar clases,
asociaciones, atributos, generalizaciones, responsabilidades u operaciones. En
particular, querrá asegurarse de que todas las asociaciones, atributos y
operaciones sean necesarias para cumplir con cierta responsabilidad, y que haya
información suficiente para cumplir con cada responsabilidad. También querrás
ver si
puede aplicar cualquiera de los
patrones de diseño discutidos en el próximo capítulo. Además, querrá
identificar las interfaces adecuadas.
■ Repita el paso anterior según sea
necesario hasta que el modelo sea satisfactorio.
Identificando clases
Hay dos formas de identificar
clases:
■ Cuando desarrolla un modelo de
dominio, tiende a descubrir clases. Se pueden encontrar en material de origen,
como descripciones de requisitos, notas de entrevistas o los resultados de
sesiones de lluvia de ideas.
■ Cuando trabaja en la interfaz de
usuario o en la arquitectura del sistema, tiende a inventar las clases
necesarias para resolver un problema de diseño en particular. A veces también
puede inventar clases al crear un modelo de dominio.
Identificar asociaciones y
atributos.
Una vez que sienta que tiene una
buena lista inicial de clases, es hora de centrar su atención en identificar
asociaciones y atributos.
La mejor manera de hacer esto es
comenzar con la clase o clases que crees que son más importantes e importantes
para el sistema.
Consejos para identificar y
especificar asociaciones válidas
Para saber si debe existir una
asociación, pregúntese si una clase posee, controla, está conectada, está
relacionada, es parte, tiene como partes, es miembro o tiene como miembros
alguna otra clase en su modelo . A menudo encontrará declaraciones de este tipo
al escanear el documento del que extrajo la lista original de clases.
Consejos sobre cómo identificar y
especificar atributos válidos
Los atributos se pueden identificar
mirando la descripción del sistema y buscando información que debe mantenerse
sobre las instancias de cada clase.
Identificar generalizaciones e
interfaces.
Hay dos formas de identificar
generalizaciones: de abajo hacia arriba y de arriba hacia abajo. El enfoque
ascendente agrupa clases similares, creando una nueva superclase, mientras que
el enfoque descendente divide una clase compleja, creando nuevas subclases.
Para utilizar el enfoque de abajo
hacia arriba, busca clases que tengan características en común. En general, si
encuentra dos o más clases que tienen atributos, asociaciones u operaciones
similares, entonces debería considerar crear una superclase común.
Asignación de responsabilidades a
las clases.
Una responsabilidad es algo que el
sistema debe hacer. La responsabilidad principal de realizar cada requisito
funcional debe atribuirse a una de las clases, aunque es probable que otras
clases colaboren con ella para ayudar a realizar la tarea.
En general, es importante
distribuir las responsabilidades entre las clases para que ninguna clase tenga
una participación injusta y, por lo tanto, se vuelva excesivamente compleja. Si
una clase tiene demasiadas responsabilidades, debe examinarla para ver si se
puede dividir en varias clases distintas. Además, todas las responsabilidades
de una clase dada deben estar claramente relacionadas entre sí y con los
atributos y asociaciones de la clase.
Una técnica de papel y lápiz para
desarrollar rápidamente un diagrama de clase.
Una técnica útil para crear
prototipos de diagramas de clase implica el uso de tarjetas pequeñas o trozos
de papel, como notas adhesivas. A medida que identifica las clases, escribe sus
nombres en las tarjetas. Puede agregar y eliminar tarjetas a medida que avanza
la técnica. Las tarjetas a menudo se llaman tarjetas CRC (Clase –
Responsabilidad – Colaboración).
A medida que identifica los
atributos y las responsabilidades, también los enumera en las tarjetas. El
hecho de que cada tarjeta tenga un espacio limitado lo alienta a no hacer que
ninguna de las clases sea excesivamente compleja. Si no puede ajustar todas las
responsabilidades en una tarjeta, esto sugiere que debe dividir la clase en dos
clases relacionadas.
Operaciones de identificación
Se necesitan operaciones para
realizar las responsabilidades de cada clase: puede haber varias operaciones
por responsabilidad, pero una estará a cargo.
La operación que se encarga de
cumplir con la responsabilidad normalmente se declarará pública. Se convierte
en parte de la interfaz de todo el subsistema. Otros métodos que colaboran para
realizar la responsabilidad serán lo más privados posible.
Implementación de diagramas de
clase en Java
■ Los atributos generalmente se
implementan como variables de instancia. Debe elegir una clase adecuada, pero
normalmente será una clase de la biblioteca estándar de Java, como String.
■ Las generalizaciones se
implementan usando la palabra clave extend, y las interfaces se implementan
usando la palabra clave implements.
Dificultades y riesgos al crear
diagramas de clase
El modelado es una habilidad
particularmente difícil. Muchas personas que son excelentes
sin embargo, los programadores
tienen dificultades considerables para pensar en el nivel de abstracción
necesario para crear modelos efectivos. Además, dado que los programas
educativos no se han centrado tradicionalmente en él, los desarrolladores de
software a menudo tienen un conocimiento significativamente menor sobre el
modelado que sobre el diseño y la programación. Tomados en conjunto, esto
significa que los proyectos de software corren el riesgo de modelos
incompletos, incorrectos o insuficientemente flexibles.
Comments
Post a Comment