El patrón adaptador, un patrón de diseño estructural, facilita la colaboración entre clases con interfaces incompatibles al convertir la interfaz de una clase en otra que el cliente espera. Esto permite reutilizar código existente sin necesidad de modificar sus implementaciones originales.
Se aplica principalmente cuando se dispone de clases con funcionalidad válida, pero sus interfaces no coinciden con las requeridas por el sistema actual. A menudo, se introduce en fases de mantenimiento o evolución del software, donde rediseñar interfaces existentes no es viable. Para evitar complejidad, se recomienda abordar discrepancias menores mediante refactorización; el adaptador se reserva para situaciones con restricciones que impidan cambios en el código fuente.
Ejemplo: Adaptación de Dispositivos en un Sistema de Control
Consideremos un sistema de domótica que necesita integrar dispositivos modernos con equipos antiguos. Primero, definimos la interfaz objetivo:
public abstract class Controlador {
protected String idEquipo;
public Controlador(String id) {
this.idEquipo = id;
}
public abstract void activar();
public abstract void desactivar();
}
Implementamos controladores concretos para dispositivos estándar:
public class ControladorIluminacion extends Controlador {
public ControladorIluminacion(String id) {
super(id);
}
@Override
public void activar() {
System.out.println("Iluminación " + idEquipo + " activada.");
}
@Override
public void desactivar() {
System.out.println("Iluminación " + idEquipo + " desactivada.");
}
}
public class ControladorRiego extends Controlador {
public ControladorRiego(String id) {
super(id);
}
@Override
public void activar() {
System.out.println("Riego " + idEquipo + " en marcha.");
}
@Override
public void desactivar() {
System.out.println("Riego " + idEquipo + " detenido.");
}
}
Para un termostato legado con interfaz diferente, creamos su clase:
public class TermostatoViejo {
private String modelo;
public String getModelo() {
return modelo;
}
public void setModelo(String modelo) {
this.modelo = modelo;
}
public void iniciar() {
System.out.println("Termostato " + modelo + " iniciado.");
}
public void parar() {
System.out.println("Termostato " + modelo + " detenido.");
}
}
El adaptador permite integrar el termostato antiguo en el sistema:
public class AdaptadorTermostato extends Controlador {
private TermostatoViejo termostato;
public AdaptadorTermostato(String modelo) {
super(modelo);
termostato = new TermostatoViejo();
termostato.setModelo(modelo);
}
@Override
public void activar() {
termostato.iniciar();
}
@Override
public void desactivar() {
termostato.parar();
}
}
El cliente utiliza todos los controladores de forma uniforme:
public class GestorSistema {
public static void main(String[] args) {
Controlador luz = new ControladorIluminacion("LUZ001");
luz.activar();
Controlador riego = new ControladorRiego("RIEGO002");
riego.desactivar();
Controlador termostato = new AdaptadorTermostato("TERM003");
termostato.activar();
}
}