Поиск по сайту:

Шаблон проектирования адаптера в Java


Шаблон проектирования адаптера является одним из шаблонов структурного проектирования и используется для совместной работы двух несвязанных интерфейсов. Объект, который объединяет эти несвязанные интерфейсы, называется адаптером.

Шаблон проектирования адаптера

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);
	}
}

Теперь мы хотим создать адаптер, который может выдавать 3 вольта, 12 вольт и 120 вольт по умолчанию. Итак, прежде всего мы создадим интерфейс адаптера с этими методами.

package com.journaldev.design.adapter;

public interface SocketAdapter {

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

Двухсторонний шаблон адаптера

При реализации шаблона адаптера существует два подхода — адаптер класса и адаптер объекта, однако оба эти подхода дают одинаковый результат.

  1. Адаптер класса. Эта форма использует наследование Java и расширяет исходный интерфейс, в нашем случае класс Socket.
  2. Адаптер объекта. Эта форма использует композицию Java, а адаптер содержит исходный объект.

Шаблон проектирования адаптера — адаптер класса

Вот реализация подхода адаптера класса для нашего адаптера.

package com.journaldev.design.adapter;

//Using inheritance for adapter pattern
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);
	}

}

Шаблон проектирования адаптера — реализация адаптера объекта

Вот реализация адаптера объекта для нашего адаптера.

package com.journaldev.design.adapter;

public class SocketObjectAdapterImpl implements SocketAdapter{

	//Using Composition for adapter pattern
	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);
	}
}

Обратите внимание, что обе реализации адаптера почти одинаковы и реализуют интерфейс SocketAdapter. Интерфейс адаптера также может быть абстрактным классом. Вот тестовая программа для использования нашей реализации шаблона проектирования адаптера.

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();
		}
	}
}

Когда мы запускаем вышеуказанную тестовую программу, мы получаем следующий вывод.

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

Диаграмма классов шаблона проектирования адаптера

Пример шаблона проектирования адаптера в JDK

Некоторые из примеров шаблонов проектирования адаптеров, которые я мог бы легко найти в классах JDK:

  • java.util.Arrays#asList()
  • java.io.InputStreamReader(InputStream) (возвращает средство чтения)
  • java.io.OutputStreamWriter(OutputStream) (возвращает модуль записи)

Это все, что касается шаблона проектирования адаптера в java.