Decomposition
Pregunta e intención
Decomposition responde cómo dividimos un sistema en unidades significativas de responsabilidad y qué fronteras establecemos entre ellas. Identifica qué existe, qué decide cada parte y qué conocimiento o efectos debería mantener dentro de su límite. Una unidad puede ser un módulo, una capacidad o un agrupamiento de servicios; su significado necesita contexto.
Es una decisión arquitectónica cuando condiciona cambios, colaboración, datos, operación o responsabilidades relevantes. No exige separar procesos. Tampoco supone que el conjunto deba dividirse hasta obtener las piezas más pequeñas posibles. La evaluación comienza con architectural-drivers, necesidades y consecuencias que interesa controlar.
El Knowledge Map V0.3 presenta Decomposition como fundamento y como Decision Axis. Aquí existe un único canonical; architecture-decision-axes lo observa junto con dependency-structure y communication. Son preguntas diferentes con decisiones que interactúan, no pasos que deban completarse en orden.
Criterios de división y decisiones que cambian
Parnas muestra que el criterio utilizado para dividir importa tanto como los módulos resultantes. Su trabajo contrasta una división por pasos de procesamiento con otra que oculta decisiones de diseño susceptibles de cambio. El módulo representa una asignación de responsabilidad, no necesariamente un subprograma. On the Criteria To Be Used in Decomposing Systems into Modules, 1972.
Eso invita a preguntar qué conocimiento queremos localizar: representación de datos, reglas de autorización, interacción con un proveedor o política de reserva. No convierte information hiding en el único criterio válido ni obliga a encapsular toda decisión imaginable antes de construir.
Pueden importar capacidad de negocio, responsabilidad de dominio, feature, caso de uso, responsabilidad técnica, ownership, variación esperada, autoridad sobre datos o necesidades de runtime y deployment. No es una lista exhaustiva. Un criterio apropiado para una dimensión puede necesitar complementarse con otro en el interior de una unidad.
Ejemplo común: comercio online
Consideremos una plataforma Commerce con estas responsabilidades ilustrativas:
| Unidad | Responsabilidad | Frontera que conviene aclarar |
|---|---|---|
| Orders | Registrar pedidos y mantener su estado de negocio. | Qué transiciones admite y qué resultados externos necesita. |
| Payments | Interpretar operaciones y resultados de pago. | Qué contrato ofrece sin exponer detalles del proveedor. |
| Inventory | Determinar y registrar disponibilidad y reservas. | Quién puede modificar una reserva y bajo qué condiciones. |
| Shipping | Preparar y seguir el envío físico. | Qué información acepta y cómo informa su progreso. |
Los nombres no demuestran que el corte sea adecuado. Hay que acordar quién decide una cancelación, cómo se distingue autorizar de capturar un pago y qué significa confirmar una reserva. Identificar responsabilidades ambiguas es parte del diseño; agregarlas todas a un módulo Common no elimina el problema.
La tabla representa unidades y fronteras. components permite interpretar esas unidades en una vista; boundaries aclara qué reglas se sostienen entre ellas. Todavía no determina si Orders llama directamente a Payments, espera un resultado remoto o publica una solicitud. Tampoco decide qué representaciones privadas puede conocer. Esas cuestiones continúan en Dependency Structure y Communication usando las mismas unidades.
Cohesión, coupling y localidad de cambio
La cohesión pregunta si las responsabilidades agrupadas tienen una razón significativa para permanecer juntas. Coupling observa conocimiento y restricciones entre partes. Ninguna se demuestra contando clases o usando nombres del negocio.
Si cambiar un proveedor de pagos obliga a modificar Orders, Inventory y Shipping porque todos interpretan sus códigos privados, el corte no localizó esa variación. Una frontera contractual puede reducir propagación; también agrega traducción, mantenimiento y decisiones de compatibilidad. No conviene ocultar esas obligaciones detrás de una promesa de independencia.
modifiability permite evaluar un cambio concreto y su radio de propagación. evolvability examina adaptación sostenida. Cambios transversales legítimos siguen existiendo: una nueva regla comercial puede requerir revisar varias responsabilidades aunque sus límites sean claros. No todo cambio distribuido demuestra una descomposición defectuosa.
Decomposition frente a Code Partitioning
Crear Orders/, Payments/ e Inventory/ puede reflejar responsabilidades o solamente mover archivos. code-partitioning-strategies pregunta cómo organizar física y conceptualmente código. Decomposition establece unidades significativas y límites con consecuencias sobre responsabilidad, encapsulación, dependencias, datos, equipos o ejecución.
Una nueva carpeta o project no crea automáticamente autoridad ni acceso restringido. Si Orders sigue modificando tablas y clases privadas de Payments, el nombre del directorio no conservó la frontera. A la inversa, un lenguaje puede proteger módulos sin requerir un repositorio o proceso por unidad.
Controllers, Services y Repositories pueden organizar responsabilidades técnicas. No equivalen a capacidades Orders, Payments e Inventory. layered-architecture desarrolla reglas entre capas; una división por negocio puede usar capas dentro de sus módulos. La combinación necesita límites compatibles, no una elección universal entre dos árboles de carpetas.
Granularity y Modularity
Decomposition decide unidades y fronteras; granularity describe cuán gruesas o finas son para el análisis considerado. Payments puede ser una unidad amplia. Authorization, Capture, Refund y Settlement pueden ser partes internas o unidades separadas si responsabilidades y drivers justifican ese corte.
Granularity no se deduce solamente del número de archivos. Una unidad pequeña puede concentrar una política crítica y otra extensa reunir comportamiento cohesivo. Dividir cada operación podría multiplicar contratos y coordinación sin mejorar el cambio que necesitamos.
modularity añade propiedades de las unidades y relaciones, como encapsulación y colaboración controlada. Un sistema dividido no es automáticamente modular. Es posible tener muchas partes que comparten todos sus detalles; también módulos protegidos dentro de un deployment común. La revisión necesita observar accesos reales y no solo el dibujo.
Descomposición jerárquica
Podemos representar diferentes niveles:
Commerce Platform
└── Orders
├── Placement
├── Fulfillment
└── CancellationEl nivel adecuado depende de la pregunta. Para analizar responsabilidades del negocio, Orders puede ser una sola unidad; para revisar cambios de cancelación, importa su interior. Las fronteras de un nivel no sustituyen decisiones de otro.
internal-structure organiza alternativas dentro de una unidad. Una capacidad puede usar Ports and Adapters o Vertical Slice sin alterar necesariamente el corte externo. Views and Beyond distingue las estructuras y relaciones representadas por vistas relevantes; no hay que confundir una organización de módulos con toda la arquitectura de runtime. SEI: Views and Beyond Collection.
Unidades conceptuales, procesos y entrega
La misma división amplia admite variantes:
| Variante ilustrativa | Realización e interacción |
|---|---|
| A | Módulos en un proceso con llamadas locales. |
| B | Módulos en un proceso con mensajería interna. |
| C | Servicios entregados por separado con llamadas de red síncronas. |
| D | Servicios entregados por separado con mensajería asíncrona. |
Estas variantes no son arquitectónicamente equivalentes. Cambian fallos, tiempos, entrega, datos y capacidades operativas. Lo que puede conservarse es el reparto amplio de responsabilidades; su realización debe volver a evaluarse.
monolith y modular-monolith permiten observar unidades dentro de una frontera de entrega. service-based-architecture, service-oriented-architecture y microservices describen paquetes con otros énfasis y condiciones. Un profile no se determina contando unidades ni representa solamente Decomposition.
Separar deployment tampoco prueba un buen límite. Si los servicios necesitan cambiar juntos por acceder a representaciones privadas, los artefactos separados no recuperan independencia. deployability ayuda a evaluar entrega efectiva, no una propiedad supuesta por el nombre.
Datos, ownership y equipos
Acordar qué responsabilidad controla una representación evita que varias unidades modifiquen la misma política accidentalmente. Un schema compartido puede ocultar dependencias aunque no exista llamada directa. data-ownership desarrolla la autoridad sobre ese estado; aquí importa reconocer la consecuencia del corte sin convertir división de unidades y autoridad en la misma pregunta.
Ownership de código, autoridad de negocio y responsabilidad operacional pueden distribuirse de manera diferente. Asignar un equipo por caja no garantiza coordinación suficiente, contratos estables ni capacidad de operar sus fallos. Los límites necesitan personas y mecanismos que puedan sostenerlos.
El despliegue físico puede separar ciertas fallas y conservar otras mediante recursos comunes. Un proceso compartido también puede contener accesos internos sin aislar CPU o memoria. La frontera debe especificar qué protege y qué sigue compartido.
Compromisos y revisión
Un corte más fino puede favorecer cambios localizados, entrega o scaling de una capacidad. También puede aumentar comunicación, coordinación, superficie operacional y costo. operability y cost-efficiency permiten evaluar esas consecuencias sin convertir distribución en una escala de madurez.
Para revisar Commerce, elegir cambios reales: otro proveedor de pagos, una reserva parcial, cancelación después de preparar envío y crecimiento concentrado en Orders. Identificar qué unidades cambian, qué contratos permanecen y qué incertidumbre apareció. Los ejemplos no demuestran de antemano que alguna variante sea superior.
Conservar una frontera necesita evidencia de responsabilidad, accesos y efectos. Si los cambios contradicen el criterio original, puede revisarse la división. Decomposition aporta un modelo explicable del sistema; no una justificación para multiplicar carpetas, servicios o abstracciones.