Patrón de diseño Adaptador en Java

El patrón de diseño del adaptador es uno de los patrones de diseño estructurales y se utiliza para que dos interfaces no relacionadas puedan trabajar juntas. El objeto que une estas interfaces no relacionadas se llama un Adaptador.

Patrón de Diseño del Adaptador

Uno de los grandes ejemplos de la vida real del patrón de diseño del adaptador es el cargador de móvil. La batería del móvil necesita 3 voltios para cargarse, pero el enchufe normal produce ya sea 120V (EE. UU.) o 240V (India). Así que el cargador de móvil funciona como un adaptador entre el enchufe de carga del móvil y el enchufe de la pared. Intentaremos implementar un adaptador múltiple utilizando el patrón de diseño del adaptador en este tutorial. Así que en primer lugar tendremos dos clases – Volt (para medir voltios) y Socket (que produce voltios constantes de 120V).

package com.journaldev.design.adapter;

public class Volt {

	private int volts;
	
	public Volt(int v){
		this.volts=v;
	}

	public int getVolts() {
		return volts;
	}

	public void setVolts(int volts) {
		this.volts = volts;
	}
	
}
package com.journaldev.design.adapter;

public class Socket {

	public Volt getVolt(){
		return new Volt(120);
	}
}

Ahora queremos construir un adaptador que pueda producir 3 voltios, 12 voltios y por defecto 120 voltios. Así que en primer lugar crearemos una interfaz de adaptador con estos métodos.

package com.journaldev.design.adapter;

public interface SocketAdapter {

	public Volt get120Volt();
		
	public Volt get12Volt();
	
	public Volt get3Volt();
}

Patrón de Adaptador de Doble Vía

Mientras se implementa el patrón Adaptador, hay dos enfoques: el adaptador de clase y el adaptador de objeto; sin embargo, ambos enfoques producen el mismo resultado.

  1. Adaptador de Clase – Esta forma utiliza la herencia en Java y extiende la interfaz fuente, en nuestro caso la clase Socket.
  2. Adaptador de Objeto – Esta forma utiliza la composición en Java y el adaptador contiene el objeto fuente.

Patrón de Diseño Adaptador – Adaptador de Clase

Aquí está la implementación del enfoque de adaptador de clase de nuestro adaptador.

package com.journaldev.design.adapter;

//Usando herencia para el patrón adaptador
public class SocketClassAdapterImpl extends Socket implements SocketAdapter{

	@Override
	public Volt get120Volt() {
		return getVolt();
	}

	@Override
	public Volt get12Volt() {
		Volt v= getVolt();
		return convertVolt(v,10);
	}

	@Override
	public Volt get3Volt() {
		Volt v= getVolt();
		return convertVolt(v,40);
	}
	
	private Volt convertVolt(Volt v, int i) {
		return new Volt(v.getVolts()/i);
	}

}

Patrón de Diseño Adaptador – Implementación del Adaptador de Objeto

Aquí está la implementación del adaptador de objeto de nuestro adaptador.

package com.journaldev.design.adapter;

public class SocketObjectAdapterImpl implements SocketAdapter{

	//Usando composición para el patrón adaptador
	private Socket sock = new Socket();
	
	@Override
	public Volt get120Volt() {
		return sock.getVolt();
	}

	@Override
	public Volt get12Volt() {
		Volt v= sock.getVolt();
		return convertVolt(v,10);
	}

	@Override
	public Volt get3Volt() {
		Volt v= sock.getVolt();
		return convertVolt(v,40);
	}
	
	private Volt convertVolt(Volt v, int i) {
		return new Volt(v.getVolts()/i);
	}
}

Ten en cuenta que ambas implementaciones del adaptador son casi iguales e implementan la interfaz SocketAdapter. La interfaz del adaptador también puede ser una clase abstracta. Aquí tienes un programa de prueba para consumir nuestra implementación del patrón de diseño de adaptador.

package com.journaldev.design.test;

import com.journaldev.design.adapter.SocketAdapter;
import com.journaldev.design.adapter.SocketClassAdapterImpl;
import com.journaldev.design.adapter.SocketObjectAdapterImpl;
import com.journaldev.design.adapter.Volt;

public class AdapterPatternTest {

	public static void main(String[] args) {
		
		testClassAdapter();
		testObjectAdapter();
	}

	private static void testObjectAdapter() {
		SocketAdapter sockAdapter = new SocketObjectAdapterImpl();
		Volt v3 = getVolt(sockAdapter,3);
		Volt v12 = getVolt(sockAdapter,12);
		Volt v120 = getVolt(sockAdapter,120);
		System.out.println("v3 volts using Object Adapter="+v3.getVolts());
		System.out.println("v12 volts using Object Adapter="+v12.getVolts());
		System.out.println("v120 volts using Object Adapter="+v120.getVolts());
	}

	private static void testClassAdapter() {
		SocketAdapter sockAdapter = new SocketClassAdapterImpl();
		Volt v3 = getVolt(sockAdapter,3);
		Volt v12 = getVolt(sockAdapter,12);
		Volt v120 = getVolt(sockAdapter,120);
		System.out.println("v3 volts using Class Adapter="+v3.getVolts());
		System.out.println("v12 volts using Class Adapter="+v12.getVolts());
		System.out.println("v120 volts using Class Adapter="+v120.getVolts());
	}
	
	private static Volt getVolt(SocketAdapter sockAdapter, int i) {
		switch (i){
		case 3: return sockAdapter.get3Volt();
		case 12: return sockAdapter.get12Volt();
		case 120: return sockAdapter.get120Volt();
		default: return sockAdapter.get120Volt();
		}
	}
}

Al ejecutar el programa de prueba anterior, obtenemos la siguiente salida.

v3 volts using Class Adapter=3
v12 volts using Class Adapter=12
v120 volts using Class Adapter=120
v3 volts using Object Adapter=3
v12 volts using Object Adapter=12
v120 volts using Object Adapter=120

Diagrama de Clase del Patrón de Diseño del Adaptador

Ejemplo del Patrón de Diseño del Adaptador en JDK

Algunos ejemplos del patrón de diseño del adaptador que pude encontrar fácilmente en las clases JDK son;

  • java.util.Arrays#asList()
  • java.io.InputStreamReader(InputStream) (devuelve un Reader)
  • java.io.OutputStreamWriter(OutputStream) (devuelve un Writer)

Eso es todo para el patrón de diseño del adaptador en Java.

Source:
https://www.digitalocean.com/community/tutorials/adapter-design-pattern-java