03‐Conceptos Fundamentales - UTOQINGAPP/Arquitectura-CMI GitHub Wiki
3. Conceptos Fundamentales
La Arquitectura CMI se basa en una estructura jerárquica compuesta por Capas, Módulos, Contenedores y Enrutadores.
Estos elementos son la base de la organización y deben aplicarse de forma estricta para garantizar la coherencia, el orden y la escalabilidad del proyecto.
A continuación, se definen cada uno de estos conceptos esenciales.
3.1 Capas
Las Capas en la Arquitectura CMI representan la división estructural más rígida y fundamental.
Esta separación no es arbitraria, sino el resultado de una necesidad clara: mantener el orden a nivel macro en cualquier proyecto, sin importar su tamaño o complejidad.
En muchas arquitecturas flexibles, es común que las responsabilidades se mezclen con el tiempo, especialmente bajo presión de crecimiento o cambios rápidos.
Este desorden puede empezar de forma imperceptible —una función de lógica dentro de la interfaz, una configuración incrustada en el núcleo de la aplicación— pero a medida que el proyecto evoluciona, estas pequeñas decisiones generan una estructura difícil de mantener, escalar y entender.
CMI resuelve este problema desde el inicio estableciendo un sistema de capas fijas e inalterables que separan claramente:
- La configuración técnica global (
configs/
). - La lógica de negocio y datos (
core/
). - Los puntos de entrada o presentación:
interface/
en backend (API, CLI, events) y en frontend (presentación e interacción con el usuario).
¿Por qué CMI impone capas estrictas?
- Para evitar personalizaciones estructurales subjetivas.
- Para mantener una organización coherente sin importar el equipo o la escala del proyecto.
- Para asegurar que cada cambio ocurre dentro de su contexto correcto, minimizando riesgos estructurales.
Esta rigidez no es una limitación, sino una herramienta que protege la salud del proyecto a largo plazo.
Consecuencias de ignorar la separación de capas
- Dificultad para localizar o modificar funciones específicas.
- Aumento del acoplamiento.
- Crecimiento desordenado donde lógica, configuración e interfaz se entrelazan.
- Refactorizaciones costosas en etapas avanzadas.
⚠️ Ignorar la jerarquía de capas no es una mala práctica: es una ruptura directa de la arquitectura CMI.
3.2 Módulos
Los Módulos en CMI son la respuesta al crecimiento descontrolado dentro de una misma Capa.
Aunque las Capas dividen el proyecto a nivel macro, dentro de cada una el código tiende a expandirse rápidamente.
Los Módulos aíslan funcionalidades específicas dentro de cada Capa, asignando espacios definidos a cada bloque de código.
¿Por qué existen los Módulos en CMI?
- Para dividir lógicamente cada área funcional dentro de cada Capa.
- Para aplicar el principio de separación de responsabilidades también a nivel de organización de carpetas.
- Para facilitar el crecimiento independiente de cada funcionalidad.
- Para evitar los "cajones de sastre" (todo mezclado en una sola carpeta).
Diferencia con otras arquitecturas
- En otras arquitecturas los módulos se crean a criterio del equipo → riesgo de inconsistencias.
- En CMI los módulos son fijos (Módulos Estándar).
- Los módulos adicionales sólo se crean si existe necesidad funcional justificada.
Errores comunes al gestionar módulos
- No usar módulos → desorden dentro de las capas.
- Crear módulos por costumbre sin necesidad real.
- Duplicar funcionalidades entre módulos.
- Omitir los enrutadores dentro de los módulos → ruptura del encapsulamiento.
¿Cuándo crear un módulo adicional?
- Sólo cuando exista una necesidad clara de aislamiento funcional que no pueda resolverse mediante contenedores dentro de un módulo existente.
- Crear módulos por comodidad es un error grave en CMI.
3.3 Contenedores
Los Contenedores son herramientas esenciales para mantener el orden a nivel micro dentro de cada Módulo.
Su función es organizar los tipos de archivos según sus responsabilidades.
¿Por qué son esenciales los contenedores en CMI?
- Permiten localizar fácilmente los archivos.
- Refuerzan la cohesión funcional.
- Evitan carpetas arbitrarias.
- Preparan la estructura para el crecimiento futuro.
- Facilitan mantenibilidad y escalabilidad, incluso en equipos grandes.
Tipos de Contenedores en CMI
Contenedores Estándar (de uso obligatorio):
Contenedor | Descripción |
---|---|
services/ |
Contratos de servicios (interfaces). |
adapters/ |
Adaptadores entre entidades y almacenamiento o integración externa. |
origins/ |
Acceso a orígenes de datos (bases de datos, APIs, etc.). |
consumers/ |
Exposición pública de lógica consumible. |
handlers/ |
Manejadores de solicitudes (HTTP, CLI, Events). |
commands/ |
Comandos CLI (solo backend). |
middlewares/ |
Validadores HTTP. |
guards/ |
Validaciones de acceso (permiso/autenticación). |
rules/
):
Contenedores de Dominio (obligatorios dentro de data/
→ Agrupa entidades, contratos de datos, value objects.- Dentro de
data/
se organizan subdominios por carpetas (por ejemplo:user/
,token/
,recovery/
).
Contenedores Adicionales (opcional, sólo si es necesario):
cli/
,shared/
, etc., dependiendo de necesidades específicas.
Contenedores Genéricos (estructuras internas adicionales):
components/
,dialogs/
,logic/
(enshared/
).container/
,group/
,category/
,part/
,internal/
,view/
(en cualquier contenedor según contexto).
Recursividad en Contenedores
- Se permite profundización cuando es necesaria.
- Siempre debe ser controlada y justificada.
- El abuso de la recursividad genera estructuras difíciles de leer.
Errores comunes al trabajar con contenedores
- Ignorar los contenedores estándar.
- Crear carpetas personalizadas donde ya existe un contenedor estándar.
- Mezclar tipos de archivos (por ejemplo: poner adaptadores dentro de
services/
). - Abusar de la recursividad sin necesidad.
- No crear el enrutador correspondiente.
❗ Crear estructuras personalizadas fuera del patrón aprobado desorganiza el sistema y debilita su escalabilidad.
3.4 Enrutadores
Los Enrutadores son el núcleo del encapsulamiento estructural en CMI.
Toda interacción entre Capas, Módulos o Contenedores debe pasar por sus respectivos Enrutadores.
El enrutador:
- Controla la visibilidad de los elementos.
- Evita accesos directos a archivos internos.
- Refuerza el bajo acoplamiento.
¿Por qué son fundamentales los enrutadores?
- Control de acceso: Bloquean importaciones directas de archivos internos.
- Encapsulamiento real: Exponen sólo lo diseñado para ser visible.
- Mantenibilidad: Cambios internos no afectan al resto del sistema mientras el enrutador mantenga el contrato.
- Claridad de dependencias: Toda importación visible pasa por los enrutadores.
- Refuerzo jerárquico: Definen los límites formales de acceso por nivel.
Tipos de Enrutadores en CMI
Enrutadores Normales
- Se utilizan en todos los niveles (capas, módulos, contenedores).
- Son el único punto de acceso público para su contexto.
Enrutadores Compuestos
En algunos casos dentro de la arquitectura CMI, un archivo puede asumir simultáneamente la función de raíz estructural y funcional de su propia estructura.
Este patrón se denomina Enrutador Compuesto.
Un Enrutador Compuesto:
- Se encuentra dentro de una estructura (por ejemplo: layouts/, pages/, overlays/, dialogs/, flows/, authentication/, http/, cli/, events/, etc.).
- Gestiona la construcción, configuración, lógica y dependencias internas de su estructura.
- Expone públicamente los elementos internos que necesitan ser accesibles desde el exterior.
Se aplica cuando:
- Existe un punto central de inicialización funcional (visual, lógica o de infraestructura).
- Toda la lógica principal se mantiene centralizada dentro del archivo raíz.
- Puede incluir navegación, subestructuras o vistas internas, siempre encapsuladas bajo su lógica principal.
Errores comunes al gestionar enrutadores
- Omitir enrutadores obligatorios.
- Exportar todos los elementos internos sin control.
- Acceso directo no autorizado a archivos internos.
- No actualizar enrutadores al modificar contenido.
- Incluir lógica o visualización dentro de enrutadores normales (excepto en enrutadores compuestos donde está permitido).
3.5 Relación Jerárquica de CMI
Capa
└── Módulo
└── Contenedor
└── Elementos: servicios, adaptadores, lógica, componentes, vistas, etc.
3.6 Ejemplo Visual de Estructura
Backend:
lib/
├── configs/
│ ├── env/
│ ├── constants/
│ ├── logger/
│ └── configs.dart # Enrutador de Configs
│
├── core/
│ ├── rules/
│ │ ├── data/
│ │ ├── services/
│ │ ├── consumers/
│ │ └── rules.dart # Enrutador de Rules
│ │
│ ├── uses/
│ │ ├── consumers/
│ │ ├── adapters/
│ │ ├── services/
│ │ ├── origins/
│ │ └── uses.dart # Enrutador de Use
│ │
│ └── core.dart # Enrutador de Core
│
├── interface/
│ ├── http/
│ │ ├── routes/
│ │ ├── handlers/
│ │ └── http.dart # Enrutador del módulo HTTP
│ │
│ ├── cli/
│ │ ├── commands/
│ │ └── cli.dart # Enrutador del módulo CLI
│ │
│ ├── events/
│ │ ├── listeners/
│ │ └── events.dart # Enrutador del módulo Events
│ │
│ ├── shared/
│ │ ├── middlewares/
│ │ └── shared.dart # Enrutador del módulo Shared
│ │
│ └── interface.dart # Enrutador de Interface
│
└── main.dart
Frontend:
lib/
├── configs/
│ └── configs.dart # Enrutador de Configs
├── core/
│ ├── rules/
│ │ └── services/
│ │ └── socket_service_rule.dart
│ └── use/
├── interface/
│ ├── layouts/
│ │ └── authentication/
│ │ ├── components/
│ │ └── views/
│ └── shared/
└── main.dart