💡 Ver Caso Práctico: Ejemplo Práctico del Patrón Proxy
Proxy es un patrón de diseño estructural que proporciona un sustituto o marcador de posición de otro objeto, controlando el acceso al objeto original.
Propósito y Caso de Uso
Utiliza Proxy cuando necesites añadir un comportamiento (caché, control de acceso, carga diferenciada, logging) alrededor de un objeto sin modificarlo, y sin que el cliente note la diferencia porque el proxy implementa la misma interfaz. A diferencia del Patrón Adapter (traduce interfaz) y del Patrón Decorator (añade responsabilidades), Proxy mantiene la misma interfaz y controla el acceso.
Estructura del Patrón
- Interfaz Común: Declarada tanto por el objeto real como por el proxy.
- Sujeto Real (RealSubject): El objeto original con la lógica de negocio.
- Proxy: Implementa la misma interfaz, mantiene una referencia al sujeto real y controla el acceso a él (lazy-loading, caché, permisos).
Flujo de Funcionamiento
- Invocación: El cliente llama a un método sobre el proxy, creyendo que es el objeto real.
- Control: El proxy ejecuta lógica adicional (verificar caché, permisos, inicializar el objeto real si aún no existe).
- Delegación: El proxy delega la llamada al sujeto real cuando corresponde y devuelve el resultado.
Ejemplos de Implementación Reales
interface DataService {
fetchData(id: string): Promise<string>;
}
class RealDataService implements DataService {
async fetchData(id: string): Promise<string> {
console.log(`Consultando API para ${id}...`);
return `datos-de-${id}`;
}
}
// Proxy con caché
class CachingDataServiceProxy implements DataService {
private cache = new Map<string, string>();
constructor(private readonly real: DataService) {}
async fetchData(id: string): Promise<string> {
if (this.cache.has(id)) {
return this.cache.get(id)!; // Sin llamar al sujeto real
}
const result = await this.real.fetchData(id);
this.cache.set(id, result);
return result;
}
}
const service: DataService = new CachingDataServiceProxy(new RealDataService());
await service.fetchData('user-1'); // Consulta real
await service.fetchData('user-1'); // Desde caché, sin llamadaCuándo NO usarlo
Si no necesitas controlar el acceso (caché, permisos, lazy-loading) y solo quieres añadir comportamiento visible al cliente, revisa primero Decorator (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 →).