┌──────────────────────────────────────────────┐
│ UI (Ribbon, Forms, Panels) │ ← Solo escucha eventos. Solo ejecuta órdenes.
├──────────────────────────────────────────────┤ No conoce nada abajo. Decide cómo "pintarse".
│ Domain Managers + Domain Events │ ← Cambian estado. Después notifican (RaiseEvent).
├──────────────────────────────────────────────┤
│ Mediators (Infra + Domain) │ ← Orquestan. Conectan. Reenvían. NO emiten eventos.
├──────────────────────────────────────────────┤
│ Infrastructure (ExecutionContextMgr, FileMgr)│ ← Conoce Excel. Emite eventos semánticos.
├──────────────────────────────────────────────┤
│ Domain (Entities, State, Interfaces) │ ← No conoce Workbook/Worksheet/Range/Application.
└──────────────────────────────────────────────┘
[ Evento técnico Excel/FS ]
↓
[ ExecutionContextListener (ThisWorkbook) ] ← Captura, reenvía sin semántica. Zero RaiseEvent.
↓ (llamada a método)
[ ExecutionContextMgr ] ← Traduce → actualiza State → RaiseEvent semántico
↓ (eventos semánticos de infraestructura)
[ Mediador de Infraestructura ] ← Escucha. Decide a qué Mgr llamar. NO emite.
↓ (métodos)
[ Domain Managers ] ← Ejecutan lógica. Actualizan State. RaiseEvent dominio.
↓ (eventos de dominio)
[ UI / Ribbon / Forms ] ← Escucha eventos. Se invalida.
Mgr ──owns──► State (composición: el Mgr crea y posee el State)
AppState ──refs──► all States (solo referencias para consultas coherentes)
- Nunca emiten eventos (RaiseEvent)
- Nunca tienen Property Let/Set públicos ni Friend (excepto métodos como Register/Clear/Reset llamados SOLO por su Mgr)
- Nunca toman decisiones ni validan
- Solo exponen Property Get (consultas de estado)
- Métodos permitidos: RegisterX, Clear, Snapshot, Reset (llamados por su Mgr)
- Ejecutan lógica imperativa (métodos, Property Let como equivalente a método)
- Actualizan su State (composición)
- Emiten eventos DESPUÉS de que el estado haya cambiado (notificación de hecho consumado)
- Un Manager solo emite eventos sobre estado que ÉL controla
- El flujo SIEMPRE es: Lógica → Actualiza State → RaiseEvent
- Conectan publicadores con consumidores
- NO emiten eventos de negocio (ni de cualquier tipo)
- Conocen a las clases de infraestructura y de dominio
- Las clases de infraestructura NO conocen al mediador
- Consolida estado de todos los subsistemas (solo referencias, no posesión)
- Permite consultas coherentes de estado global
- Facilita logging y diagnósticos
- NO controla nada. NO da órdenes. NO emite eventos.
- Solo tiene Property Gets (fachada de lectura)
- Capa más superior: nada la conoce
- Solo escucha eventos (decide cómo pintarse)
- Puede ejecutar órdenes (llamar métodos en Mgrs)
- Se invalida en respuesta a eventos, no por llamadas desde abajo
- La aplicación debe funcionar sin UI
-
Técnicos: Excel, FileSystem, COM, Host (WorkbookOpen, SheetActivate)
- Capturados por ExecutionContextListener
- No tienen semántica de dominio
-
Semánticos de Infraestructura: Traducción de los técnicos
- Emitidos por ExecutionContextMgr (que es un Manager, no un Mediator)
- Ejemplos: WorkbookSessionStarted, ActiveChartChanged, FileBecameReadOnly
-
De Dominio: Notificación de que algo ya ha ocurrido
- Emitidos SOLO por Domain Managers
- Ejemplos: OpportunityActivated, CollectionUpdated
- Un evento es notificación de hecho consumado, NUNCA señal de inicio
- El Dominio define contratos (interfaces): qué necesita, no cómo se obtiene
- La Infraestructura implementa: traduce tecnología → contrato
- Ejemplo: IOpportunitySource (dominio) ← ExcelOpportunitySource (infraestructura)
- El Dominio nunca referencia Workbook, Worksheet, Range directamente
INCORRECTO: mRibbon.InvalidateControl "btnGuardar" ← Infraestructura sabe que hay Ribbon
CORRECTO:
Infrastructure/Domain → RaiseEvent StateChanged(...)
clsRibbon ← Sub mSource_StateChanged(...) → Me.Invalidate
- Property Get: Vive en State o en Manager (como fachada). Solo consulta. No dispara eventos.
- Property Let/Set en Manager: Equivalente a método imperativo. Solo si el significado es "establecer el actual" y no hay lógica compleja.
- Property Let/Set en State: PROHIBIDO. Convierte el estado en anárquico.
- UI escucha TODOS los eventos (técnicos, semánticos, de dominio)
- Otros Mgrs escuchan eventos cuando es necesario (FileMgr → OpportunitiesMgr)
- La escucha se hace A TRAVÉS DE MEDIADORES, nunca directa entre Mgrs
- Estado → Mgr: NUNCA
- clsExecutionContext debe permitir: reenganchar eventos, reconstruir estado derivado, aislar el daño del reset
- Si Excel/VBA se resetea, solo se rompa infraestructura (NO dominio, NO UI, NO coordinadores)
- Eventos de ciclo de vida: ContextInvalidated(), ContextReinitialized()
- Solo clsExecutionContextMgr puede manejar reset/reenganche