Directriz: Paquete de diseño
Un paquete de diseño es una construcción que se utiliza para partir el modelo de diseño. En esta directriz se explica cómo identificar y especificar paquetes de diseño.
Relaciones
Elementos relacionados
Descripción principal

Introducción

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.

Visibilidad del contenido del paquete

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.

Criterios de partición de 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.

Clase de límite de paquete

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.

Diagrama descrito en el texto adjunto.

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.

Diagrama descrito en el texto adjunto.

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.

Clases relacionadas con la funcionalidad de paquete

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.

Diagrama descrito en el texto adjunto.

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.

Diagrama descrito en el texto adjunto.

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.

Cohesión del paquete de evaluación

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'.

Diagrama descrito en el texto adjunto.

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'.

Descripción de las dependencias del paquete

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.

Diagrama descrito en el texto adjunto.

El paquete Gestión de pedido depende de Gestión de elemento, porque existe una asociación entre dos clases de los paquetes.

Acoplamiento del paquete de evaluación

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.

Diagrama descrito en el texto adjunto.

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.

Diagrama descrito en el texto adjunto.

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.