El patrón Adapter convierte la interfaz de una clase en otra, que es la que esperan los clientes. Permite que clases con interfaces incompatibles trabajen juntas.
El problema que resuelve es la incompatibilidad de interfaces. Surge cuando queremos usar una clase existente, pero su interfaz no se corresponde con la que necesitamos.
La solución que propone el Adapter es:
 
              Este patrón es recomendable cuando:
Reutilización de Código Permite reutilizar código existente, incluso si sus interfaces no coinciden con las que se necesitan.
Separación de Código: El código de la aplicación se mantiene separado del código del adaptador, mejorando así la modularidad y separación de responsabilidades.
Flexibilidad: Se pueden agregar o eliminar adaptadores sin alterar el código existente.
Desventajas
Introduce complejidad: Agrega clases y objetos, lo que puede complicar el diseño.
Rendimiento: Es un caso para sistemas muy críticos, puede haber una pequeña baja en el rendimiento por la capa adicional de abstracción.
Debemos invocar un servicio externo que retorna el detalle de los impuestos a calculados en el mes, la respuesta viene en formato XML. Eso lo debemos enviar al sistema interno de contabilidad, pero en formato JSON.
El problema es que hay una incompatibilidad en la comunicación, por un lado recibimos un XML y por el otro debemos enviar un JSON. Necesitamos hacer que dos sistemas incompatibles trabajen juntos.
Solución planteada
Implementamos un Adapter, vamos a cambiar el formato de los datos de XML a JSON, para enviarlos al servicio interno de contabilidad.
Tenemos la clase XMLDataProvider, que contiene la respuesta que nos da el proveedor, los datos están en formato XML. Definimos la interfaz JSONDataProvider, lo que el cliente espera usar, datos en formato JSON, y finalmente creamos el Adapter, la clase XMLToJSONAdapter, que hace la conversión de XML a JSON.
 
              Codificamos en Java lo que preparamos en el diagrama.
Tenemos la clase XMLDataProvider, que se comunica con el sistema externo y retorna los datos en XML:
    public class XMLDataProvider {
        public String getXMLData() {
            //retorna el resultado de la invocación a la API al sistema externo
            return "<result>"
                    + "<month>March</month>"
                    + "<total>100</total>"
                    + "</result>";
        }
    }
              Definimos la interfaz JSONDataProvider:
    public interface JSONDataProvider {
        String getJSONData();
    }
              Creamos el Adapter, que realiza la conversión de XML a JSON:
    public class XMLToJSONAdapter implements JSONDataProvider {
        private XMLDataProvider xmlDataProvider;
    
        public XMLToJSONAdapter(XMLDataProvider xmlDataProvider) {
            this.xmlDataProvider = xmlDataProvider;
        }
    
        public String getJSONData() {
            String xmlStr = xmlDataProvider.getXMLData();
            //Lógica para convertir XML a JSON
            ...
            //Retorna el String en formato JSON
            return "{'result': {'month': 'March', 'total': 100}}";
        }
    }
              El código cliente, obtiene los datos del proveedor e invoca al servicio interno de contabilidad pasandole los datos en formato JSON:
    class Client {
        public static void main(String[] args) {
            XMLDataProvider xmlProvider = new XMLDataProvider();
            JSONDataProvider dataProvider = new XMLToJSONAdapter(xmlProvider);
            //Llamamos al servicio interno que recibe el JSON
            sendTaxReport(dataProvider.getJSONData());
        }
    }
              Los participantes que vimos antes son: Adaptee, Target, Adapter, Client:
Este es un caso clásico y efectivo del patrón Adapter, que facilitó la integración de dos sistemas con formatos de datos incompatibles, un problema muy común en la integración de servicios y sistemas.
Tiene una estructura similar pero un propósito diferente: separar la interfaz de su implementación, mientras que el Adapter está pensado para cambiar la interfaz de un objeto existente.
Decora otro objeto sin cambiar su interfaz, es más transparente que un Adapter.
Define un representante o sustituto de un objeto sin cambiar su interfaz.