El modelo de diseño se puede estructurar en unidades
más pequeñas para facilitar la comprensión. Agrupando los elementos de modelo de diseño en paquetes y subsistemas y
mostrando, a continuación, como se relacionan estas agrupaciones entre si, es más fácil de comprender la estructura
global del modelo. Tenga en cuenta que un subsistema de diseño se modela como un componente que realiza una o más
interfaces; para obtener más información, consulte el apartado Producto de trabajo: Subsistema de diseño y Directriz de producto de trabajo: Subsistema de diseño. Los paquetes de diseños, por
otra parte, son sólo para agrupar.
Una clase contenida en un paquete puede ser pública o privada. Una clase pública se puede
asociar a otra clase. Una clase privada se puede asociar sólo a clases contenidas en
el paquete.
Una interfaz de paquete consta sólo de las clases públicas del paquete. La interfaz del paquete (clases públicas)
aíslan e implementan las dependencias de otros paquetes. De este modo, el desarrollo paralelo se simplifica porque
puede establecer las interfaces antes, y los desarrolladores necesitarán conocer sólo los cambios de las interfaces de
otros paquetes.
Puede partir el modelo de diseño por una serie de motivos:
-
Puede utilizar los paquetes y subsistemas como orden, configuración, o unidades de entrega cuando un sistema ha
finalizado.
-
La asignación de recursos y la competencia de diferentes equipos de desarrollo puede requerir que el proyecto se
divida entre diferentes grupos en diferentes sitios. Los subsistemas, con interfaces definidas, proporcionan un
modo de dividir el trabajo entre equipos de forma controlada y coordinada, permitiendo que el diseño y la
implementación se desarrollen en paralelo.
-
Los subsistemas se pueden utilizar para estructurar el modelo de diseño de modo que refleje los tipos de usuario.
Muchos requisitos de cambio se originan en los usuarios; los subsistemas garantizan que estos cambios de un tipo de
usuario concreto afectarán sólo a los componentes del sistema que corresponden a ese tipo de usuario.
-
En algunas aplicaciones, cierta información debe estar accesible sólo para unas cuantas personas. Los subsistemas
le permiten mantener la privacidad en áreas donde es necesario.
-
Si está construyendo un sistema de soporte, puede, mediante subsistemas y paquetes para darle una estructura
similar a la estructura del sistema que se soporta. De este modo, puede sincronizar el mantenimiento de dos
sistemas.
-
Los subsistemas se utilizan para representar
los productos existentes y los servicios que utiliza el sistema (por ejemplo, productos COTS, y bibliotecas), tal
como se explica en las secciones siguientes.
Cuando se distribuyen las clases de límite a paquetes, existen dos estrategias diferentes que se pueden aplicar; cuál
escoger depende de si las interfaces del sistema pueden cambiar mucho en el futuro o no.
-
Si es probable que la interfaz del sistema se reemplace, o que sufra cambios considerables, la interfaz debe
separarse del resto del modelo de diseño. Cuando la interfaz de usuario se haya cambiado, sólo afectará a estos
paquetes. Un ejemplo de cambio importante es la conmutación de una interfaz orientada a la línea a una interfaz
orientada a ventana.
Si el objetivo principal es simplificar los cambios de interfaz más importantes, las clases de límite se colocarán en
uno (o varios) paquetes separados.
-
Si no se han planificado cambios importantes en la interfaz, los cambios de los servicios del sistema deben ser el
principio de orientación, en lugar de los cambios de la interfaz. Las clases de límite se colocarán entonces todas
juntas con las clases de entidad y control con las que están funcionalmente relacionadas. De este modo, será fácil
ver qué clases de límite están afectadas si se cambia una cierta clase de entidad o de control.
Para simplificar los cambios a los servicios del sistema, las clases de límite se empaquetan con las clases con las que
están funcionalmente relacionadas.
Las clases de límite obligatorias que no están funcionalmente relacionadas con cualquier entidad- o clases de control,
se deben colocar en paquetes separados, junto con las clases de límite que pertenecen a la misma interfaz.
Si una clase de límite está relacionada con un servicio opcional, agrúpela con las clases que colaboran para
proporcionar el servicio, en un subsistema separado. El subsistema se correlacionará con un componente opcional que se
proporcionará cuando se solicite la funcionalidad opcional.
Un paquete debe identificarse para cada grupo de clases que estén funcionalmente relacionadas. Existen varios criterios
prácticos que se pueden aplicar al juzgar si dos clases están funcionalmente relacionadas. Son, en orden de importancia
decreciente:
-
Si los cambios en el comportamiento y/o estructura de una clase requieren cambios en otra clase, las dos clases
están funcionalmente relacionadas.
Ejemplo
Si se añade un nuevo atributo a la clase de entidad Pedido, es muy probable que requiera la actualización de
la clase de control Administrador de pedidos. Por lo tanto, pertenecen al mismo paquete, Gestión de
pedidos.
-
Es posible descubrir si una clase está funcionalmente relacionada con otra empezando por una clase - por ejemplo,
una clase de entidad - y examinando el impacto de eliminarla del sistema. Las clases que sean superfluas como
resultado de la eliminación de una clase están conectadas de algún modo con la clase eliminada. Por superfluas,
queremos decir que la clase sólo la utiliza la clase eliminada, o que depende de la clase eliminada.
Ejemplo
Existe un paquete Gestión de pedidos que contiene dos clases de control Administrador de pedidos y
Registrador de pedidos, en el Sistema de gestión de almacén. Las dos clases de control modelan
servicios respecto a la gestión de pedidos en el depósito. Todos los atributos de pedido y las relaciones se
almacenan por la clase de entidad Pedido, que sólo existe para la gestión de pedidos. Si se elimina la clase
de entidad, no habrá necesidad de Administrador de pedidos o Registrador de pedidos, porque sólo son
útiles si el Pedido existe. Por lo tanto, la clase de entidad Pedido deberá incluirse en el mismo
paquete que las dos clases de control.
Administrador de pedidos y Registrador de pedidos pertenecen al mismo paquete que Pedido,
porque resultan superfluos si se elimina Pedido del sistema.
-
Dos objetos pueden estar funcionalmente relacionados si interactúan con un gran número de mensajes, o si tienen una
intercomunicación complicada.
Ejemplo
La clase de control Realizador de tareas envía y recibe muchos mensajes desde y hacia la Interfaz del
transportador Esta es otra indicación que se debe incluir en el mismo paquete, Gestión de tareas.
-
Una clase de límite puede estar funcionalmente relacionada con una clase de entidad concreta si la función de la
clase de límite es presentar la clase de entidad.
Ejemplo
La clase de límite Formulario de palet, en el Sistema de gestión de almacén, presenta una instancia
de la clase de entidad Palet al usuario. Cada Palet se representa con un número de identificación en
la pantalla. Si la información sobre un Palet se cambia, por ejemplo, si el Palet también tiene un
nombre, la clase de límite puede tener que cambiarse también. El Formulario de palet deberá incluirse en el
mismo paquete que Palet.
-
Dos clases pueden estar funcionalmente relacionadas si interactúan con, o están afectadas por, el mismo actor. Si
dos clases no implican al mismo actor, no deben encontrarse en el mismo paquete. La última norma se puede omitir
por motivos más importantes.
Ejemplo
Hay un paquete Gestión de tareas en el Sistema de gestión de almacén, que incluye, entre otras, la
clase de control Realizador de tareas. Este es el único paquete implicado con el actor Transportador,
el transportador físico que puede transportar un palet en el almacén. El actor interactúa con la clase de control
Realizador de tareas a través de la clase de límite Interfaz de transportador. Esta clase de límite
deberá incluirse en el paquete Gestión de tareas.
Interfaz de transportador y Realizador de tareas pertenecen al mismo paquete ya que ambos están
afectados por los cambios del actor Transportador.
-
Dos clases pueden estar funcionalmente relacionadas si existen relaciones entre ellas (asociaciones, agregaciones,
etc.). Por supuesto, este criterio no se puede seguir descuidadamente, sino que se puede utilizar cuando no sea
aplicable ningún otro criterio.
-
Una clase puede estar funcionalmente relacionada con la clase que crea instancias de esta.
Estos dos criterios determinan cuando dos clases no deben colocarse en el mismo paquete:
-
Dos clases que estén relacionadas con actores diferentes no deben colocarse en el mismo paquete.
-
Una clase opcional y una clase obligatoria no deben colocarse en el mismo paquete.
Primero, todos los elementos de un paquete deben tener la misma condición de opcional: no puede haber elementos de
modelo opcionales en un paquete obligatorio.
Ejemplo
La clase de entidad obligatoria Tipo de artículo tiene, entre otros, un atributo denominado Reabastecer el
umbral. La función de reabastecer, sin embargo, es opcional en el sistema. Por lo tanto, Artículo debe
dividirse en dos clases de entidad, donde la clase opcional se relaciona con la clase obligatoria.
Un paquete que se considere obligatorio no puede depender de ningún paquete que se considere opcional.
Por norma, dos actores diferentes no pueden utilizar un único paquete. El motivo para esto es que un cambio en el
comportamiento de un actor no debería afectar también a otros actores. Existen excepciones a esta regla, como para los
paquetes que constituyen servicios opcionales. Los paquetes de este tipo no deben dividirse, independientemente de
cuantos actores lo utilicen. Por lo tanto, divida cualquier paquete, o clase, que utilizan varios paquetes, a menos que
el paquete sea opcional.
Todas las clases del mismo paquete deben estar funcionalmente relacionadas. Si ha seguido los criterios de la sección
"Encontrar paquetes de clases funcionalmente relacionadas", las clases de un paquete estarán funcionalmente
relacionadas entre si. Sin embargo, una clase particular puede contener por si misma "demasiado" comportamiento, o
relaciones que no pertenecen a la clase. Parte de la clase debería eliminarse para convertirla en una clase totalmente
nueva, o en cualquier otra clase, que probablemente pertenecerá a otro paquete.
Ejemplo
El comportamiento de una clase de control A, en un paquete no debe depender demasiado de una clase, B, en
otro paquete. Para aislar el comportamiento específico B, la clase de control A debe dividirse en dos
clases de control, A' y A". El comportamiento específico B se coloca en la nueva clase de control,
A", que se coloca en el mismo paquete que B. La nueva clase A" también obtiene una relación, como
generalización, con el objeto original A'.
Para aislar el comportamiento específico B, la clase de control A, a la que falta homogeneidad, se divide
en dos clases de control, A' y A'.
Si una clase en un paquete tiene una asociación con una clase en un paquete diferente, estos paquetes dependen del
otro. Las dependencias de los paquetes se modelan mediante la relación de dependencia entre los paquetes. Las
relaciones de dependencia nos ayudan a valorar las consecuencias de los cambios: un paquete del que dependen muchos
paquetes es más difícil de cambiar que uno del que no depende ningún paquete.
Como se descubrirán varias dependencias como esta durante la especificación de los paquetes, estas relaciones pueden
cambiar durante el trabajo. La descripción de una relación de dependencia puede incluir información sobre qué
relaciones de clase han causado la dependencia. Como esto introduce información que es difícil de mantener, debe
llevarse a cabo sólo si la información es pertinente y de valor.
Ejemplo
En el Sistema de gestión de almacén, existe la relación de dependencia del paquete Gestión de pedidos al
paquete Gestión de elementos. Esta asociación surge porque la clase de entidad Pedido de Gestión de
pedido tiene una asociación con la clase de entidad Tipo de elemento en el paquete de pedido.
El paquete Gestión de pedido depende de Gestión de elemento, porque existe una asociación entre dos
clases de los paquetes.
El acoplamiento de paquetes es positivo y negativo: positivo, porque el acoplamiento representa la reutilización, y
negativo, porque el acoplamiento representa las dependencias que dificultan el cambio y la evolución del sistema. Se
pueden seguir algunos principios generales:
-
Los paquetes no se deben acoplar de forma cruzada (es decir, no deben ser codependientes); por ejemplo, dos
paquetes no deberían depender el uno del otro.
En estos casos, los paquetes deben reorganizarse para eliminar las dependencias cruzadas.
-
Los paquetes de las capas inferiores no deberían depender de los paquetes de las capas superiores. Los paquetes
sólo deberían depender de los paquetes de la misma capa y de la capa inferior siguiente.
En estos casos, la funcionalidad debe repartirse. Una solución es indicar las dependencias en términos de
interfaces, y organizar las interfaces de la capa inferior.
-
En general, las dependencias no deberían omitir las capas, a menos que el comportamiento dependiente sea común a
través de todas las capas, y la alternativa es simplificar el paso a través de las invocaciones de operación a
través de las capas.
-
Los paquetes no deben depender de los subsistemas, sólo de otros paquetes o de interfaces.
|