Patrón Adapter
El patrón Adapter permite que dos interfaces incompatibles colaboren envolviendo una de ellas en un objeto traductor. Úsalo cuando necesites integrar una librería de terceros, una clase legada o cualquier API cuya firma no coincida con la que espera tu código.
Resumen
El patrón Adapter (también llamado Wrapper) actúa de puente entre dos interfaces que nunca fueron pensadas para hablarse. En lugar de reescribir la clase original —que puede ser de terceros, legada o simplemente costosa de modificar—, se construye un objeto fino que expone la interfaz que tu código espera y delega internamente en la que ya existe. Es la forma clásica de encajar una pieza cuadrada en un agujero redondo sin tocar ninguno de los dos lados.
Cuándo usarlo
- Necesitas usar una clase existente pero su interfaz no coincide con la que espera tu código.
- Estás integrando un SDK de terceros o un módulo legado que no puedes (o no debes) modificar.
- Quieres aislar al resto del sistema de una API externa volátil tras un contrato interno estable.
Ejemplo
interface Logger {
log(message: string): void;
}
class ThirdPartyLogger {
writeMessage(level: string, payload: { msg: string }) {
console.log(`[${level}] ${payload.msg}`);
}
}
class ThirdPartyLoggerAdapter implements Logger {
constructor(private readonly external: ThirdPartyLogger) {}
log(message: string): void {
this.external.writeMessage("info", { msg: message });
}
}
const logger: Logger = new ThirdPartyLoggerAdapter(new ThirdPartyLogger());
logger.log("App iniciada");Ventajas
- Permite reutilizar código existente sin modificarlo.
- Desacopla tu dominio de APIs legadas o de terceros.
- Responsabilidad única: la traducción vive en una clase con nombre claro.
Desventajas
- Añade una capa extra de indirección que hay que mantener junto al original.
- Un adaptador bidireccional puede volverse un compromiso complejo.
- Fácil de abusar — a veces refactorizar al consumidor es más limpio que envolver al servicio.