Patron de Diseño Adapter en Java

El patrón de diseño Adapter te sirve cuando tienes interfaces diferentes o incompatibles entre sí y necesitas que el cliente pueda usar ambas del mismo modo.

El patrón de diseño Adapter dice en su definición que convierte una interfaz o clase en otra interfaz que el cliente necesita.

Cuales son las partes del patrón de diseño Adapter

Las partes de patrón Adapter son

  • Target: la interfaz que usamos para crear el adapter.
  • Adapter: es la implementación del target y que se ocupará de realizar la adaptación.
  • Client: es el que interactúa y usa el adapter.
  • Adaptee: es la interfaz incompatible que necesitamos adaptar con el adapter.

Patron Diseño Adapter Java

Como se crea el patrón de diseño Adapter en Java

Mencionamos antes que el patrón tenía varias partes. Un cliente que interactúa con el Adapter para conseguir lo que necesita. El Target de la cual se implementar el Adapter, quien será el encargado de adaptar la respuesta del Adaptee para que el Client la entienda. El Adaptee que representa la clase con una interfaz incompatible para el cliente

Patron Diseño Adapter Java

Llevemos esto a un ejemplo en el cual un Cliente necesita información de un servicio BankService que devuelve la información en la clase BankData.

  1. Client: el cliente necesita información de una cuenta bancaria y la necesita en la clase User.
  2. Client: el cliente llama al adapter para conseguir información del User
  3. Adapter: el adapter llama al servicio para que devuelva información.
  4. Adaptee: el servicio devuelve el BankUser, el Adaptee.
  5. Adapter: el adapter convierte BankData en User y la devuelve al client.
  6. Client: el cliente recibe la info en User. La clase que si entiende.

Patron Diseño Adapter Java

El servicio que devuelve BankData


package patterns.adapter;

public class BankService {

    public BankData findByAccountNumber(int accountNumber) {
        if (accountNumber == 1) {
            return new BankData(accountNumber,"Nick", 100d);
        } else if (accountNumber == 3) {
            return new BankData(accountNumber,"Susan", 200d);
        } else {
            return null;
        }
    }
}

La clase BankData con la info


package patterns.adapter;

public class BankData {

    private int account;
    private String name;
    private double balance;

    public BankData(int account, String name, double balance) {
        this.account = account;
        this.name = name;
        this.balance = balance;
    }

    public String getName() {
        return name;
    }

    public int getAccount() {
        return account;
    }

    public double getBalance() {
        return balance;
    }
}

La clase User que requiere el cliente


package patterns.adapter;

public class User {

    private int id;
    private String name;
    private double totalAvailable;

    public User(int id, String name, double totalAvailable) {
        this.id = id;
        this.name = name;
        this.totalAvailable = totalAvailable;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public double getTotalAvailable() {
        return totalAvailable;
    }
}

El target (interfaz) de la cual creamos el Adapter

package patterns.adapter;

public interface UserAdapter {

    User getUser(int accountNumber);

}

La implementación del adapter

package patterns.adapter;

public class UserAdapterImpl implements UserAdapter {

    private BankService service = new BankService();

    @Override
    public User getUser(int accountNumber) {
        BankData bankData = service.findByAccountNumber(accountNumber);
        User user = new User(bankData.getAccount(), bankData.getName(), bankData.getBalance());
        return user;
    }
}

El client que necesita información en la clase User

package patterns.adapter;

public class Client {

    public static void main(String[] args) {

        UserAdapterImpl adapter = new UserAdapterImpl();
        adapter.getUser(1);

    }
}

Conclusión

Hemos visto que el patrón Adapter resuelve incompatibilidades entre interfaces adaptando una interfaz hacia la otra utilizando un adapter encargado de la conversión entre interfaces.

Se trata de un patrón muy utilizado sobre todo cuando nos comunicamos con apis externas y necesitamos adaptar su respuesta hacia nuestras interfaces.

Puedes descargar este código en github

Hi! If you find my posts helpful, please support me by inviting me for a coffee :)

Ver también