💡 Ver Caso Práctico: Ejemplo Práctico del Patrón Flyweight
Flyweight (Peso Ligero) es un patrón de diseño estructural que permite mantener más objetos dentro de la memoria RAM disponible, compartiendo partes comunes de su estado entre múltiples objetos en lugar de duplicarlas en cada instancia.
Propósito y Caso de Uso
Utiliza Flyweight cuando necesites crear una gran cantidad de objetos similares (miles de iconos, caracteres de texto, partículas en un juego) y una parte significativa de su estado sea idéntica entre instancias. Se separa el estado intrínseco (compartido, inmutable: ej. la textura de un icono) del estado extrínseco (único por instancia: ej. su posición en pantalla).
Estructura del Patrón
- Flyweight: Almacena el estado intrínseco compartido y expone un método que recibe el estado extrínseco como parámetro.
- Fábrica Flyweight: Gestiona un pool de flyweights, devolviendo uno existente si ya se creó con esos datos intrínsecos, o creando uno nuevo si no.
- Contexto (Cliente): Mantiene el estado extrínseco y lo pasa al flyweight en cada llamada.
Flujo de Funcionamiento
- Solicitud a la fábrica: El cliente pide un flyweight pasando su estado intrínseco (ej. tipo de icono, color base).
- Reutilización: La fábrica busca en su caché interna; si ya existe uno con esos datos, lo devuelve sin crear uno nuevo.
- Uso con contexto: El cliente invoca al flyweight pasando el estado extrínseco variable (posición, tamaño) en cada llamada.
Ejemplos de Implementación Reales
class IconFlyweight {
constructor(private readonly svgPath: string, private readonly baseColor: string) {}
render(x: number, y: number): string {
// svgPath y baseColor son compartidos; x/y son el estado extrínseco
return `<svg x="${x}" y="${y}" fill="${this.baseColor}"><path d="${this.svgPath}"/></svg>`;
}
}
class IconFactory {
private static pool = new Map<string, IconFlyweight>();
static get(type: string, svgPath: string, baseColor: string): IconFlyweight {
const key = `${type}-${baseColor}`;
if (!this.pool.has(key)) {
this.pool.set(key, new IconFlyweight(svgPath, baseColor));
}
return this.pool.get(key)!;
}
}
// 10,000 iconos de "check" reutilizan la MISMA instancia, solo cambia x/y
for (let i = 0; i < 10000; i++) {
const icon = IconFactory.get('check', 'M5 12l5 5L20 7', 'green');
icon.render(i * 10, 0);
}
console.log(IconFactory['pool'].size); // 1 — un solo flyweight creadoCuándo NO usarlo
Si el número de objetos es pequeño o su estado casi no se comparte, Flyweight añade complejidad de gestión de pool sin ahorro real de memoria (YAGNIGlosarioYAGNI (You Aren't Gonna Need It)Principio de Extreme Programming (XP) que establece que un programador no debe añadir funcionalidad hasta que sea estrictamente necesario. Su objetivo es evitar la sobre-ingeniería (over-engineering), previniendo código para funcionalidades hipotéticas.Ver término completo →).