Components

Elementos con significado arquitectónico

Un component representa un elemento significativo para razonar sobre responsabilidades, comportamiento o estado del sistema en una vista determinada. Su utilidad depende de lo que permite explicar: qué hace, con quién interactúa, qué decisiones concentra y qué consecuencias tendría cambiarlo o perderlo.

En el Atlas usamos esta orientación como convención editorial amplia, no como definición universal de cualquier notación. La palabra element es más general; component suele destacar una parte que realiza responsabilidades o conserva estado. Una caja no adquiere ese significado únicamente por recibir un nombre.

Orders, Payments, Inventory y Shipping pueden ser components de Commerce en una vista de responsabilidades. Esa vista no afirma todavía que sean cuatro servicios, procesos, repositorios, contenedores o equipos. Para interpretar las cajas hay que declarar sistema observado, propósito de la vista y relaciones representadas.

La vista y el nivel de detalle

Views and Beyond distingue vistas de módulos, centradas en unidades de código, vistas de components and connectors, centradas en elementos que interactúan durante ejecución, y vistas de asignación al entorno. Esas categorías ayudan a no interpretar una representación como si explicara todas las estructuras. SEI: Comparing Views and Beyond with ANSI-IEEE 1471-2000, sección 2.2.

Un component de una vista de runtime puede ser un proceso, un cliente, un subsistema de almacenamiento o un worker. En una conversación sobre responsabilidades puede representar una capacidad realizada por varias unidades. Conviene nombrar la vista y mantener su interpretación consistente; mezclar niveles sin indicarlo produce comparaciones engañosas.

Payments puede aparecer como una unidad cuando analizamos colaboración con Orders. Para revisar conciliación y autorización, su interior puede mostrar partes diferentes. En una vista de despliegue interesan instancias, ubicación y recursos. Refinar el dibujo para otra pregunta no significa que la responsabilidad original haya desaparecido.

granularity permite precisar qué tan gruesas o finas son las unidades en la vista elegida; la granularidad necesaria depende del análisis. Dibujar cada clase puede esconder responsabilidades entre cientos de detalles. Agrupar toda Commerce en una caja puede ocultar autoridad sobre pagos. Elegir elementos consiste en conservar información pertinente, no en perseguir un tamaño universal.

Cuándo una parte merece atención

architectural-significance permite preguntar qué consecuencias merecen tratamiento arquitectónico. Un component puede importar por su responsabilidad comercial, estado autoritativo, colaboración crítica, propagación de cambios, fallo o exposición de capacidades. No necesita ser grande en líneas de código.

Un pequeño adaptador puede concentrar una dependencia contractual importante. Una colección extensa de utilidades puede no ser una unidad útil para el problema analizado. Ni tamaño ni dificultad de implementación bastan para decidir el papel de una parte.

Una descripción útil aclara qué obligación asume el component, qué datos interpreta, qué requiere de otros y qué permanece dentro de su límite. También identifica si estamos describiendo una intención o una estructura ya observada. Las responsabilidades declaradas necesitan contrastarse con acceso a datos, imports y operación real.

Component no es class, DLL ni container

Una clase puede realizar parte de un component, o representar una unidad significativa en una vista muy específica. No hay que convertir cada clase en component arquitectónico por defecto. Un conjunto de clases también puede colaborar para una misma responsabilidad.

Una DLL o un paquete identifica una forma de distribución o compilación. Un container empaqueta ejecución y dependencias. Ambos pueden corresponder a components, pero esa correspondencia requiere explicar su propósito. Un container puede ejecutar varias responsabilidades; una responsabilidad puede necesitar varios artefactos.

Crear carpetas Orders y Payments no prueba que existan límites efectivos. Si todas las partes manipulan estado privado de las demás, los nombres organizan archivos sin conservar el reparto declarado. boundaries permite precisar qué regla debería detener ese acceso.

Estas distinciones evitan tomar la herramienta de implementación como unidad inevitable del modelo. También permiten discutir una arquitectura antes de elegir su empaquetado, sin desconectarla de las condiciones reales de construcción y operación.

Component y module: variación terminológica

Module suele enfatizar organización estática del código; component suele destacar un elemento de runtime o una responsabilidad arquitectónica. Es una orientación útil, no una separación rígida válida para todos los autores. Algunas fuentes emplean component para unidades de implementación y otras usan module como asignación de responsabilidad.

Parnas trata el módulo como una asignación de responsabilidad, y advierte que distintas divisiones pueden producir representaciones ejecutables comparables. Ese uso impide reducir module a archivo o subprograma, y explica por qué nuestra convención no declara que todo módulo sea exclusivamente estático. Parnas: On the Criteria To Be Used in Decomposing Systems into Modules, 1972.

Al leer otra fuente, preguntar qué significa el término allí antes de traducirlo a una caja del Atlas. Si una vista agrupa módulos de código y otra representa instancias ejecutándose, documentar la correspondencia. No deducir que una asociación entre módulos muestra una llamada entre procesos.

Component y service

Un servicio puede ser un component arquitectónico; component no significa necesariamente servicio de red. Un cliente de escritorio, un worker de conciliación, un subsistema de base de datos o un sistema externo también pueden ser elementos relevantes de una vista.

Service tampoco debe interpretarse automáticamente como endpoint remoto. Un lenguaje o framework puede llamar service a una unidad local. La conversación necesita aclarar qué capacidad presta y qué relación tiene con sus consumidores.

Payments podría realizarse como módulos dentro de una aplicación o como un servicio con entrega separada. La responsabilidad de interpretar pagos puede mantenerse comparable, mientras cambian comunicación, fallos y obligaciones operacionales. El nombre del component no garantiza equivalencia entre esas realizaciones.

Component y unidad de deployment

deployment pregunta qué se instala, actualiza o revierte como unidad. Un component lógico puede compartir un artefacto con otros. También puede necesitar varias réplicas ejecutándose, sin que cada réplica constituya una responsabilidad comercial distinta.

El SEI distingue components de una vista C&C y unidades concretas de implementación o deployment: su relación puede ser indirecta. Tomamos esa advertencia para exigir una correspondencia explícita cuando se pasa del modelo de colaboración al empaquetado ejecutable. SEI: Documenting Component and Connector Views with UML 2.0, sección 2.

Si Payments tiene tres réplicas, importan sus identidades operativas y el estado que comparten. No corresponde contar tres capacidades de pago en la vista de responsabilidades. A la inversa, entregar una única aplicación no obliga a modelar una sola responsabilidad.

Commerce: mismos nombres, realizaciones distintas

ComponentResponsabilidad que conserva el ejemplo
OrdersMantener el ciclo de vida del pedido y sus decisiones comerciales.
PaymentsInterpretar autorización, captura y resultados de pago.
InventoryResolver disponibilidad y reservas de existencias.
ShippingPreparar y seguir el envío del pedido.

En una variante, esas responsabilidades se implementan como módulos en un modular-monolith. En otra, algunos components se realizan mediante servicios y workers con entregas separadas. Dentro de cada alternativa hay decisiones pendientes sobre contratos, estado y colaboración.

Payments expone capacidades mediante interfaces, interactúa con otras partes mediante connectors y conserva reglas de autoridad mediante boundaries. Esas perspectivas complementan la descripción del component; no sustituyen su responsabilidad por una lista de herramientas.

Que Shipping use un worker no significa que todo Shipping sea un worker. Puede haber una entrada para programar envíos, un procesamiento diferido y almacenamiento. La vista elegida determina si esas realizaciones aparecen separadas o dentro de una unidad mayor.

Decomposition y profiles

decomposition pregunta cómo dividir el sistema y qué criterios justifican las unidades. Components son algunos elementos con los que representamos el resultado en ciertas vistas. Descomponer no se reduce a crear components ni obliga a elegir un mecanismo específico de interacción.

architecture-profile organiza paquetes de respuestas sobre varias dimensiones. El número de components no identifica el perfil. Un monolito puede contener muchas responsabilidades claras; un sistema de microservices puede tener unidades ambiguas y cambios que propaguen detalles privados.

Agregar components tampoco mejora automáticamente modularidad. Cada nueva unidad introduce responsabilidades de integración, contratos y mantenimiento. Separar algo tiene valor cuando hace más explicables sus obligaciones y consecuencias, no cuando incrementa el número de cajas.

Preguntas para revisar el modelo

Precisar qué vista usamos, qué responsabilidad representa cada elemento y por qué ese nivel ayuda a decidir. Revisar qué datos posee, qué espera de colaboradores y qué permanece compartido al fallar o cambiar.

Después contrastar el modelo con evidencia de implementación y operación. Si las fronteras reales difieren de las declaradas, registrar la diferencia antes de prometer independencia. Un buen inventario de components permite razonar sobre el sistema; no pretende que una sola lista de partes sea toda su arquitectura.