Angular 21 de Cero a Experto / Estado a gran escala
El patrón facade: una fachada simple sobre lo complejo
Una feature madura tiene varias piezas por dentro: un store, un servicio de API, quizá lógica de caché o de RxJS. Si cada componente tiene que conocer y coordinar todas esas piezas, se acoplan a los detalles internos. El patrón FACADE resuelve esto: una fachada que expone a los componentes una API SIMPLE —lo que necesitan hacer— ocultando cómo se hace por dentro. Hoy lo dominas y cierras la teoría del módulo.
La recepción del hotel
Un servicio facade
Un facade es un servicio que reúne el store, el API service y la lógica de una feature, y expone solo lo que los componentes necesitan:
import { Injectable, inject } from '@angular/core';
import { BolsilloStore } from './bolsillo.store';
import { ApiGastosService } from './api-gastos.service';
@Injectable({ providedIn: 'root' })
export class BolsilloFacade {
private store = inject(BolsilloStore);
private api = inject(ApiGastosService);
// LECTURAS: reexpone las señales del store (los componentes solo leen)
readonly gastos = this.store.gastos;
readonly total = this.store.total;
readonly saldo = this.store.saldo;
readonly cargando = this.store.cargando;
// ACCIONES: coordinan API + store por dentro
async cargar() {
this.store.setCargando(true);
const gastos = await firstValueFrom(this.api.listar());
this.store.setGastos(gastos);
this.store.setCargando(false);
}
async agregar(nombre: string, valor: number, categoria: string) {
const creado = await firstValueFrom(this.api.crear({ nombre, valor, categoria }));
this.store.agregarLocal(creado); // actualiza el store tras confirmar el servidor
}
}El componente ahora solo conoce el facade:
@Component({
selector: 'app-lista',
template: `
<p>Total: {{ bolsillo.total() }} — Saldo: {{ bolsillo.saldo() }}</p>
@for (g of bolsillo.gastos(); track g.id) { <li>{{ g.nombre }}</li> }
`,
})
export class ListaComponent {
protected bolsillo = inject(BolsilloFacade); // UNA dependencia, API simple
ngOnInit() { this.bolsillo.cargar(); }
}El componente no inyecta el store NI el API service directamente: habla solo con el facade. Si mañana cambias cómo se cargan los datos (agregas caché, cambias de API), tocas el facade y NO los componentes. Ese desacople es el valor del patrón.
Cuándo un facade ayuda (y cuándo estorba)
¿Cuál es el principal beneficio de un servicio facade?
Mini-reto
Decide para cada feature si un facade aporta o es sobreingeniería, y justifícalo: 1) "gastos", que coordina un store, un API service con caché y una lógica de invalidación; 2) "tema" (claro/oscuro), que es solo una señal en un servicio; 3) "reportes", que combina datos de gastos con llamadas a una API de análisis y transformaciones. Para las que sí, esboza la API pública del facade (qué lecturas y acciones expondría).
Qué sigue
Cierras la teoría del estado a gran escala: tipos de estado, SignalStore, arquitectura por features y el patrón facade. Tienes el criterio para estructurar una app que vive años. El reto del módulo lo integra: vas a construir un SignalStore de features para "Mi Bolsillo" con estado, derivados y acciones —el store definitivo de tu app—, probado en vivo.