자바에서 어댑터 디자인 패턴

어댑터 디자인 패턴은 구조적인 디자인 패턴 중 하나로, 두 개의 관련 없는 인터페이스가 함께 작동할 수 있도록 하는 것입니다. 이러한 관련 없는 인터페이스를 연결하는 객체를 어댑터라고 합니다.

어댑터 디자인 패턴

어댑터 디자인 패턴의 좋은 실제 예로는 모바일 충전기가 있습니다. 모바일 배터리는 충전을 위해 3볼트가 필요하지만, 일반 소켓은 120V(미국) 또는 240V(인도)를 생성합니다. 따라서 모바일 충전기는 모바일 충전 소켓과 벽 소켓 사이에서 어댑터로 작동합니다. 이 튜토리얼에서는 어댑터 디자인 패턴을 사용하여 멀티 어댑터를 구현해 보겠습니다. 먼저 Volt (볼트 측정)와 Socket (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);
	}
}

이제 3볼트, 12볼트 및 기본 120볼트를 생성할 수 있는 어댑터를 만들고자 합니다. 따라서 이러한 메소드를 가진 어댑터 인터페이스를 먼저 생성합니다.

package com.journaldev.design.adapter;

public interface SocketAdapter {

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

양방향 어댑터 패턴

어댑터 패턴을 구현하는 동안에는 두 가지 접근 방식이 있습니다. 클래스 어댑터와 객체 어댑터이지만 이 두 가지 접근 방식은 같은 결과를 생성합니다.

  1. 클래스 어댑터 – 이 형식은 자바 상속을 사용하며 소스 인터페이스를 확장합니다. 우리의 경우에는 Socket 클래스입니다.
  2. 객체 어댑터 – 이 형식은 자바 합성을 사용하며 어댑터는 소스 객체를 포함합니다.

어댑터 디자인 패턴 – 클래스 어댑터

여기는 어댑터의 클래스 어댑터 접근 방식 구현입니다.

package com.journaldev.design.adapter;

//어댑터 패턴에 상속 사용
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{

	//어댑터 패턴에 합성 사용
	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) (Reader를 반환)
  • java.io.OutputStreamWriter(OutputStream) (Writer를 반환)

자바에서의 어댑터 디자인 패턴에 대한 설명은 여기까지입니다.

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