-
Adapter Pattern(어댑터 패턴)STUDY/디자인패턴 2024. 12. 8. 15:58
어댑터 패턴이란?
호환되지 않는 인터페이스를 가진 객체들이 협업할 수 있도록 하는 구조적 디자인 패턴
문제
XML 형식의 데이터를 사용하는 앱에서 JSON 형식의 데이터로만 작동하는 라이브러리를 사용한다고 했을 때,
문제를 해결하기 위해 라이브러리를 XML과 작동하도록 변경할 수 있으나, 그러면 라이브러리에 의존하는 일부 기존 코드가 손상될 수 있고, 타사의 라이브러리 소스 코드에 접근하는 것 자체가 불가능할 수 있다.
해결책
어댑터는 한 객체의 인터페이스를 다른 객체가 이해할 수 있도록 변환하는 역할을 한다. 객체 중 하나를 래핑하여 클라이언트가 쉽게 사용할 수 있도록 변환하고, 래핑된 객체는 어댑터의 존재를 인식하지 못한다. 데이터를 다양한 형식으로 변환할 수 있을 뿐만 아니라 다른 인터페이스를 가진 객체들이 협업하는 데에도 도움을 줄 수 있다.
객체 어댑터 구조
객체 어댑터 구현은 객체 합성 원칙을 사용한다. 어댑터는 한 객체의 인터페이스를 구현하고 다른 객체는 래핑한다. 모든 프로그래밍 언어로 구현할 수 있다.
- 클라이언트 : 프로그램의 기존 비즈니스 로직을 포함하는 클래스
- 클라이언트 인터페이스 : 다른 클래스들이 클라이언트 코드와 공동 작업할 수 있도록 따라야하는 프로토콜
- 서비스 : 일반적으로 타사 또는 레거시의 유용한 클래스를 의미, 서비스 클래스는 호환되지 않는 인터페이스를 가지고 있기 때문에 클라이언트는 서비스 클래스를 직접 사용할 수 없음
- 어댑터 : 클라이언트와 서비스 양쪽에서 작동할 수 있는 클래스로, 서비스 객체를 래핑하는 동안 클라이언트 인터페이스를 구현한다. 어댑터는 인터페이스를 통해 클라이언트로부터 호출들을 수신한 후 이 호출을 래핑된 서비스 객체가 이해할 수 있는 형식의 호출들로 변환한다.
public class Service { void specificMethod(int specialData) { System.out.println("기존 서비스, " + specialData); } } public interface ClientInterface { void method(int data); } public class Adapter implements ClientInterface { Service adaptee; // composition Adapter(Service adaptee) { this.adaptee = adaptee; } public void method(String data) { int specialData = converToServiceFormat(data); adaptee.specificMethod(specialData); } public int converToServiceFormat(String data) { return Integer.parseInt(data); } } public class Client { public static void main(String[] args) { ClientInterface adapter = new Adapter(new Service()); adapter.method("1"); } }
클래스 어댑터 구조
클래스 어댑터 구현은 상속을 사용하며, 어댑터는 동시에 두 객체의 인터페이스를 상속한다. C++와 같이 다중 상속을 지원하는 프로그래밍 언어에서만 구현할 수 있다.
- 클래스 어댑터 : 클라이언트와 서비스 양쪽 인터페이스를 상속하기 때문에 객체를 래핑할 필요가 없다. 변환 로직은 오버라이딩된 메서드 내에서 발생하게 된다.
public class Service { void specificMethod(int specialData) { System.out.println("기존 서비스, " + specialData); } } interface ClinetInterface { void method(int data); } class Adapter extends Service implements ClinetInterface { public void method(String data) { int specialData = converToServiceFormat(data); specificMethod(specialData); } public int converToServiceFormat(String data) { return Integer.parseInt(data); } } public class Client { public static void main(String[] args) { ClinetInterface adapter = new Adapter(); adapter.method(1); } }
장단점
장점
- 단일 책임 원칙 : 프로그램의 기존 비즈니스 로직에서 인터페이스 또는 데이터 변환 코드를 분리할 수 있다.
- 개방/폐쇄 원칙 : 클라이언트 코드가 클라이언트 인터페이스를 통해 어댑터와 작동하는 한, 기존의 클라이언트 코드를 손상시키지 않고 새로운 유형의 어댑터들을 추가할 수 있다.
단점
- 다수의 새로운 인터페이스와 클래스들을 도입해야 하므오 코드의 복잡성이 증가한다.
참고
'STUDY > 디자인패턴' 카테고리의 다른 글
Composite Pattern(복합체 패턴) (0) 2024.12.25 Bridge Pattern(브리지 패턴) (0) 2024.12.08 Singleton Pattern(싱글턴 패턴) (0) 2024.11.26 Prototype Pattern(프로토타입 패턴) (0) 2024.11.26 Builder Pattern(빌더 패턴) (0) 2024.11.12