69 lines
2.8 KiB
Markdown
69 lines
2.8 KiB
Markdown
|
|
# Opción B — Capas sin acople (alternativa rustacean)
|
||
|
|
|
||
|
|
Demo alternativa, más sofisticada. Modela la regla de arquitectura hexagonal
|
||
|
|
"el dominio no depende de infraestructura, la aplicación no depende de
|
||
|
|
infraestructura" como contrato Nickel custom, y muestra el typecheck
|
||
|
|
rechazando una dependencia ilegal.
|
||
|
|
|
||
|
|
## Cuándo usar esta en vez de A
|
||
|
|
|
||
|
|
- Audiencia con experiencia previa en arquitectura limpia / hexagonal
|
||
|
|
- Cohorte que ya pasó por el WG y vuelve para repetir con tema más denso
|
||
|
|
- Sesión más larga (15 min en vez de 8) donde da tiempo a explicar las capas
|
||
|
|
|
||
|
|
**Para la primera sesión con audiencia mixta: usa la opción A.**
|
||
|
|
|
||
|
|
## Archivos
|
||
|
|
|
||
|
|
| Archivo | Paso de la demo | Resultado de `nickel export` |
|
||
|
|
|---|---|---|
|
||
|
|
| `core.start.ncl` | Paso 2 — sin contrato custom | ✓ exporta JSON (estructura básica) |
|
||
|
|
| `core.with-contract.ncl` | Paso 3 — contrato `ValidLayerDependency` aplicado | ✓ exporta JSON (todas las dependencias son legales) |
|
||
|
|
| `core.broken.ncl` | Paso 4 — dependencia ilegal | ✗ error: `Layer violation: user (Domain) cannot depend on db_pool (Infrastructure)` |
|
||
|
|
|
||
|
|
> **Composición de contratos**: los dos contratos (`Dependency` para la forma
|
||
|
|
> del record y `ValidLayerDependency` para la regla de capas) se aplican
|
||
|
|
> encadenados con `| Array Dependency | Array ValidLayerDependency`. No se
|
||
|
|
> mergean con `&` porque uno es record-shape y el otro es custom contract —
|
||
|
|
> el `|` los aplica secuencialmente al mismo valor.
|
||
|
|
|
||
|
|
## Concepto modelado
|
||
|
|
|
||
|
|
Tres capas:
|
||
|
|
|
||
|
|
- `'Domain` — lógica pura, no debe conocer infraestructura
|
||
|
|
- `'Application` — orquesta dominio, no debe conocer infraestructura
|
||
|
|
- `'Infrastructure` — adaptadores, puede depender de cualquier capa
|
||
|
|
|
||
|
|
Reglas codificadas en `allowed_dependency`:
|
||
|
|
|
||
|
|
| Source | Targets permitidos |
|
||
|
|
|---|---|
|
||
|
|
| `'Domain` | `'Domain` solamente |
|
||
|
|
| `'Application` | `'Domain` y `'Application` |
|
||
|
|
| `'Infrastructure` | cualquiera |
|
||
|
|
|
||
|
|
## Verificación rápida (ensayo)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd /Users/Akasha/Development/ontoref/assets/work-group-ore/demo/option-b-layers
|
||
|
|
nickel export core.start.ncl # exporta JSON
|
||
|
|
nickel export core.with-contract.ncl # exporta JSON
|
||
|
|
nickel export core.broken.ncl # falla — Layer violation: user (Domain) cannot depend on db_pool (Infrastructure)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Adaptación del guion
|
||
|
|
|
||
|
|
El guion en `../script.md` está escrito para opción A. Para opción B, los
|
||
|
|
cambios:
|
||
|
|
|
||
|
|
- **Paso 2**: tecleas la lista de dependencias sin contrato custom
|
||
|
|
- **Paso 3**: tecleas el `let allowed_dependency = ...` y el
|
||
|
|
`ValidLayerDependency` con `std.contract.custom`
|
||
|
|
- **Paso 4**: añades una dependencia `'Domain -> 'Infrastructure` y el typecheck
|
||
|
|
rechaza con el mensaje del custom contract
|
||
|
|
- **Paso 5**: arreglarlo significa o cambiar la capa del módulo origen, o
|
||
|
|
refactorizar para introducir un puerto/adapter
|
||
|
|
|
||
|
|
Tiempo: ~12-15 min en vez de 8-10.
|