본문 바로가기
SPRING

[파트 1. 스프링 입문] 챕터 2-3. 어댑터 패턴

by ZZON90 2022. 3. 14.

 디자인 패턴 중 하나인 어댑터 패턴에 대해 포스팅합니다.

 

어댑터 패턴이란?

 Adapter는 실생활에서 110V를 220V로 변경하거나 그 반대로 220V를 110V로 변경해주는 변환기를 예로 들 수 있습니다. 클래스의 인터페이스를 사용자가 기대하는 다른 인터페이스로 변환하여 사용할 수 있도록 합니다. 호환성이 없는 인터페이스 때문에 동작할 수 없는 클래스를 함께 동작할 수 있도록 해줍니다. 어댑터 패턴은 SOLID 원칙 중 개방 폐쇄 원칙(OCP)을 따릅니다.

 

예제

두 개의 Interface

public interface Electronic110V {
	public void powerOn();
}

public interface Electronic220V {
	public void connect();
}

 각각 전압이 다른 전자제품 2개가 있다고 가정합니다. 하나는 110V를 사용하는 전자제품이고 하나는 220V를 사용하는 전자제품입니다. 110V 전자제품은 powerOn 메서드를 사용하고 220V 전자제품은 connect 메서드를 사용합니다. 두 인터페이스는 호환성이 없어, 각 전자제품을 맞추기 위해서는 하나의 메서드를 변경해야 동일한 동작을 할 것입니다.

 

두 개의 실물 객체

public class Monitor implements Electronic110V {
	@Override
	public void powerOn() {
		System.out.println("110V 모니터 켜졌어요");
	}
}

public class NoteBook implements Electronic220V {
	@Override
	public void connect() {
		System.out.println("220V 노트북 켜졌어요");
	}
}

 각 전압에 맞는 전자제품 인터페이스를 구현한 모니터와 노트북이 있습니다. Monitor 클래스는 Electronic110V의 powerOn 메서드를 구현했습니다.  NoteBook 클래스도 마찬가지로 Electronic220V의 connect 메서드를 구현했습니다. 

 

 

 

호환되지 않을 때

public class AdapterMain {
	public static void main(String[] args) {
		Monitor monitor = new Monitor();
		connect(monitor);
		
		NoteBook notebook = new NoteBook();
		connect(notebook);
	}
    
	public static void connect(Electronic110V electronic110v) {
		electronic110v.powerOn();
	}
}

=> 실행결과
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The method connect(Electronic110V) in the type AdapterMain is not applicable for the arguments (NoteBook)

	at chapter2.adapter.AdapterMain.main(AdapterMain.java:10)

 모니터 한대와 노트북 한대를 콘센트에 연결한다고 가정합니다. 이 때 우리 집은 110V 콘센트를 사용합니다. connect 메서드는 110V와 호환되는 전자제품이 연결될 경우 제품의 전원을 켜줍니다. Monitor는 110V이기 때문에 정상 동작합니다. NoteBook은 220V이기 때문에 제품 전원이 들어오지 않고 문제가 발생합니다.

 

클래스를 변경하지 않고 어떻게 호환할까?

public class ConnectAdapater implements Electronic110V{
	private Electronic220V electronic220V;
	public ConnectAdapater(Electronic220V elec220v) {
		this.electronic220V = elec220v;
	}
	@Override
	public void powerOn() {
		this.electronic220V.connect();
	}
}

 NoteBook을 110V에서 동작할 수 있도록 어댑터 패턴을 사용하여 ConnectAdapter 클래스를 만들어줍니다. ConnectAdapter클래스는 Electronic110V를 구현하지만 Electronic220V를 변수로 갖고 있습니다. ConnectAdapter 클래스는 생성 시 elec220v를 받아 ConnectAdapter 내 electronic220V에 대입합니다. 그리고 powerOn 메서드 호출 시 electronic220V의 connect 메서드를 호출하게 구현합니다.

public class AdapterMain {
	public static void main(String[] args) {
		Monitor monitor = new Monitor();
		connect(monitor);
		NoteBook notebook = new NoteBook();
		// connect(notebook);
		Electronic110V adapter = new ConnectAdapater(notebook);
		connect(adapter);
	}
	
	public static void connect(Electronic110V electronic110v) {
		electronic110v.powerOn();
	}
}

=> 실행결과
110V 모니터 켜졌어요
220V 노트북 켜졌어요

 다시 Main클래스로 와서 기존 connect(notebook)은 사용하지 않고 110V를 사용하는 adpater 변수에 ConnectAdapter 생성자에 notebook 파라미터를 담아 생성합니다. 그러면 adapter는 110V 기반이지만 powerOn 메서드를 호출할 때에는 220V의 connect 메서드를 호출하는 결과를 볼 수 있습니다.

 즉, 우리가 사용해야 할 클래스는 변경하지 않고 Adapter클래스를 구현하여 110V 콘센트에서도 220V 전자제품을 사용할 수 있게 해줍니다.

댓글