Archyno
UMLDiagramas de estructura

Ejemplos de diagramas de componentes

Cinco diagramas de componentes de sistemas en los que probablemente has trabajado. Cada uno resuelve una pregunta: quién puede llamar a quién, qué tendría que cumplir un reemplazo y dónde va una dependencia en el sentido equivocado.

9 min de lecturaUML 2.5.118 de 35

La respuesta corta

  • El ejemplo más útil es el más pequeño que resuelve una discusión: dos o tres componentes, las interfaces entre ellos y nada más.
  • Los microservicios encajan limpiamente: un servicio por componente, una API publicada por interfaz. Dónde se ejecutan es un diagrama de despliegue.
  • De tres a nueve componentes. Por encima de diez el lector deja de seguir flechas y solo ojea, y el diagrama ya es decoración.
  • Dibuja el adaptador, no la base de datos. El contrato del que depende tu código es el dato que importa; el producto es infraestructura.
Un diagrama de componentes UML. Un componente de tienda web y un componente de aplicación móvil dependen ambos de una interfaz ICatalog, que realiza un único componente de servicio de catálogo.
Ejemplo uno. Dos clientes, un contrato, un proveedor: la flecha discontinua con triángulo hueco significa "esto lo implemento", la flecha discontinua simple significa "esto lo necesito".

01Cómo leer los cinco#

Todos los diagramas de abajo usan las mismas tres marcas, y si sabes leerlas puedes leer los cinco: un componente es una caja con el icono de enchufe, una «interface» es una caja que nombra un contrato, y las flechas dicen de qué lado de ese contrato está cada componente. Una flecha discontinua con triángulo hueco significa esto lo implemento. Una flecha discontinua simple significa esto lo necesito. El juego completo está en los símbolos del diagrama de componentes, y el razonamiento tras la notación en la guía del diagrama de componentes.

Están ordenados por la frecuencia con que aparece la forma y no por complejidad. Cada uno nombra la pregunta que zanja, porque un diagrama de componentes que no zanja nada es el tipo más común y el menos útil: cinco cajas, cinco flechas y ninguna afirmación con la que alguien pueda discrepar.

021. Dos clientes, un contrato#

La figura de la cabecera de este artículo. Una tienda web y una aplicación móvil necesitan datos de producto; un servicio de catálogo los proporciona. La interfaz se dibuja una vez, entre ambos.

Esa única caja es todo el sentido del ejemplo. Antes de que existiera, los dos clientes tenían dos ideas distintas de lo que devuelve «el catálogo», y la diferencia vivía en el que se escribió en segundo lugar. Nombrar ICatalog obliga a plantear qué es realmente el contrato, y una vez nombrado, un cambio en él es visiblemente un cambio para dos consumidores en vez de una edición de un servicio.

032. Puertos y adaptadores#

Un diagrama de componentes UML de un diseño de puertos y adaptadores. Un componente de API HTTP depende de una interfaz IOrdering que realiza el componente del núcleo de pedidos. El núcleo depende de una interfaz IOrderStore que realiza un componente adaptador de PostgreSQL.
Ejemplo dos. El núcleo se sitúa entre dos contratos y no depende de ninguna implementación: la API HTTP entra por IOrdering, y a la base de datos se llega por IOrderStore.

Lee las flechas y fíjate en lo que el núcleo de pedidos no toca. No depende de HTTP y no depende de PostgreSQL. Realiza un contrato y requiere otro, y ambos son cajas que podría haberle pasado cualquiera.

Esta es la forma que la gente quiere decir con arquitectura hexagonal, puertos y adaptadores o arquitectura limpia, y un diagrama de componentes es la forma más barata de comprobar si una base de código la tiene de verdad. Si la caja del núcleo tiene una flecha apuntando a un componente de base de datos en vez de a una interfaz, el patrón es una aspiración: algo del medio importa el controlador.

043. Un contrato, dos implementaciones#

Un diagrama de componentes UML. Un componente de servicio de pedidos depende de una interfaz IBilling. La realizan dos componentes: un componente de facturación heredado y un nuevo componente de servicio de facturación.
Ejemplo tres. El diagrama de migración: las dos implementaciones de facturación realizan IBilling, así que el servicio de pedidos no puede saber con cuál está hablando.

Este es el diagrama que se dibuja antes de una sustitución, no después. La afirmación que hace es precisa y comprobable: todo lo que el servicio de pedidos necesita de la facturación está en IBilling, así que una segunda implementación de esa interfaz puede sustituirse sin que el servicio de pedidos cambie.

Es además la forma más rápida de descubrir que la afirmación es falsa. Si alguien dice «el servicio nuevo no sabe generar los extractos en PDF», entonces los extractos en PDF formaban parte del contrato y faltan en la interfaz, y el diagrama estaba mal antes que la migración. Esa conversación cuesta diez minutos en una pizarra y tres meses en producción.

Cuando la implementación vieja ya no esté, bórrala del diagrama. Un diagrama de componentes que sigue mostrando el mainframe dos años después de apagarlo es la razón de que la gente deje de fiarse de los diagramas.

054. Una arquitectura de complementos#

Un diagrama de componentes UML de una arquitectura de complementos. Un componente anfitrión de editor depende de una interfaz IExporter, que realizan tres componentes: un exportador PNG, un exportador Mermaid y un exportador Sparx .qea.
Ejemplo cuatro. La misma forma que el ejemplo tres, significando algo distinto: el anfitrión no está eligiendo un exportador, está diseñado para aceptar cualquier número de ellos.

Topológicamente esto es el ejemplo tres con una tercera implementación añadida, y merece detenerse en ese parecido: reemplazabilidad y extensibilidad son el mismo dibujo. Lo que cambia es la intención. En una migración la realización extra es temporal; en una arquitectura de complementos es el producto.

La técnica de lectura que compensa aquí es tapar la columna derecha con la mano. Lo que queda - el anfitrión e IExporter- es todo lo que necesita saber quien vaya a escribir un cuarto exportador. Si la respuesta a «¿puedo escribir mi propio exportador?» exige leer el código del anfitrión, la interfaz está infraespecificada, y el diagrama acaba de decírtelo.

065. El que tiene un ciclo#

Un diagrama de componentes UML que muestra un ciclo de dependencias. El servicio Orders depende de una interfaz IShipping que realiza el servicio Shipping, y el servicio Shipping depende de una interfaz IOrders que realiza el servicio Orders.
Ejemplo cinco. Orders necesita Shipping, Shipping necesita Orders. Ninguno puede desplegarse, probarse ni sustituirse sin el otro, y el diagrama lo hace visible de un vistazo.

Dos servicios, cada uno realizando un contrato que el otro requiere. Aquí nada es UML ilegal y nada del diagrama está mal: el dibujo es una imagen exacta de un sistema que va a ser difícil, que es justo lo que quieres que un diagrama sepa decir.

Un ciclo entre componentes significa que ninguno puede entenderse solo: nada de despliegue independiente, nada de probar en aislamiento sin un sustituto del otro, y reemplazar cualquiera de los dos exige cumplir un contrato del que el otro depende a la vez. En un diagrama de clases un ciclo es un olor; entre unidades desplegables es un riesgo de calendario.

Los arreglos habituales se ven en la misma imagen. Mueve lo que Shipping necesita de IOrders a un evento que publique el servicio Orders, para que la flecha pase a ser de un solo sentido. O extrae la parte compartida a un tercer componente del que dependan ambos, lo que convierte el ciclo en una convergencia y te devuelve al ejemplo uno.

En una línea cada uno

  1. 01Convergencia (ejemplo 1): un contrato con varios consumidores; nómbralo una vez, cámbialo una vez.
  2. 02Cadena (ejemplo 2): el núcleo depende de interfaces por ambos extremos y de implementaciones por ninguno.
  3. 03Dos realizaciones (ejemplo 3): la afirmación de migración, escrita donde puede refutarse.
  4. 04Muchas realizaciones (ejemplo 4): el mismo dibujo que una migración, pensado como algo permanente.
  5. 05Un ciclo (ejemplo 5): una imagen honesta de un sistema que no puede desplegarse ni sustituirse por partes.
  6. 06Si un diagrama no zanja ninguna discusión, es decoración: bórralo en vez de mantenerlo.

Para dibujar uno de estos contra tu propio sistema, la versión paso a paso está en cómo dibujar un diagrama de componentes. Para dónde se ejecutan esos componentes en vez de qué se prometen entre ellos, eso es un diagrama de despliegue.

07Preguntas frecuentes#

¿Cómo es un buen ejemplo de diagrama de componentes?

El ejemplo más útil es el más pequeño que resuelve una discusión: dos o tres componentes, las interfaces entre ellos y nada más. Un diagrama de un catálogo compartido por la web y la app dice más que un muro de cuarenta cajas, porque se sostiene en la cabeza de una vez y se puede contrastar con el código.

¿Un diagrama de componentes puede representar microservicios?

Sí, y es uno de sus mejores usos. Cada servicio es un componente y cada API publicada una interfaz, así que el diagrama dice exactamente qué servicio puede llamar a qué contrato. Lo que no debe mostrar es dónde se ejecutan esos servicios: eso es un diagrama de despliegue.

¿Cuántos componentes debe tener un diagrama?

Entre tres y unos nueve. Por debajo de tres no hay estructura que dibujar, y por encima de nueve o diez el lector deja de seguir las flechas y solo ojea, que es cuando el diagrama se vuelve decoración. Un sistema grande se dibuja como varios diagramas, uno por pregunta.

¿Se debe dibujar la base de datos como un componente?

Dibuja el adaptador, no la base de datos. El diagrama trata del contrato del que depende tu código, así que un componente Adaptador PostgreSQL que realiza la interfaz IOrderStore lleva el dato útil. El producto de base de datos es infraestructura y corresponde al diagrama de despliegue.

En esta serie

Lecturas relacionadas

Todos los artículos