어댑터 패턴이란?
어댑터 패턴은 서로 호환되지 않는 인터페이스를 가진 객체들이 협력할 수 있도록 하는 패턴으로, 래퍼로도 불립니다. 기존에 사용했던 시스템(레거시 시스템)을 원하는 인터페이스로 사용가능하게 합니다.
어댑터 패턴의 사용 방법
클래스 어댑터 (상속)
- Adaptee : 기존 레거시 시스템
- Target: 어댑터가 구현하는 인터페이스
- Adapter: Client와 Adaptee중간에서 호환성이 없는 둘을 연결시켜주는 역할 담당
- 클래스 어댑터 방식에서는 상속을 이용해 구성
- Adaptee는 extends, Target은 implements해서 구현
- Client: 기존 시스템을 어댑터를 통해 이용하려는 쪽. Client interface를 통해 Service를 이용
// Target 인터페이스 - 새로운 인터페이스
public interface Target {
void request();
}
// Adaptee 클래스 - 기존 레거시 시스템
public class Adaptee {
public void specificRequest() {
//구현 부분
}
}
// Adapter 클래스, Target 인터페이스를 구현하고 Adaptee를 내부적으로 사용합니다.
public class Adapter extends Adaptee implements Target {
public Adapter(){
super();
}
@Override
public void request() {
// Adaptee의 specificRequest 메소드가 Target 인터페이스의 request 메소드로 매핑됩니다.
specificRequest();
}
}
// 클라이언트 코드
public class Client {
public static void main(String[] args) {
//1. 어댑터 생성
Target target = new Adapter();
//2. Client Interfac의 스펙에 따라 메소드를 실행하면 기존 서비스의 메소드가 실행
target.request();
}
}
객체 어댑터 (위임/합성)
- Adaptee : 기존 레거시 시스템
- Target: 어댑터가 구현하는 인터페이스
- Adapter: Client와 Adaptee중간에서 호환성이 없는 둘을 연결시켜주는 역할 담당
- 객체 어댑터 방식에서는 합성을 이용해 구성
- Adaptee는 따로 클래스 멤버로 설정하고 위임을 통해 동작을 매치
- Client: 기존 시스템을 어댑터를 통해 이용하려는 쪽. Client interface를 통해 Service를 이용
// Target 인터페이스 - 새로운 인터페이스
public interface Target {
void request();
}
// Adaptee 클래스 - 기존 레거시 시스템
public class Adaptee {
public void specificRequest() {
//구현 부분
}
}
// Adapter 클래스는 Target 인터페이스를 구현하고, 내부에 Adaptee 인스턴스를 합성합니다.
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
// Adaptee의 specificRequest 메소드를 호출합니다.
adaptee.specificRequest();
}
}
// 클라이언트 코드
public class Client {
public static void main(String[] args) {
//1. 어댑터 생성(기존 서비스를 인자로 받아 호환 작업 처리)
Target target = new Adapter(new Adaptee());
//2. Client Interfac의 스펙에 따라 메소드를 실행하면 기존 서비스의 메소드가 실행
target.request();
}
}
패턴 사용 시기
정리하자면 구 버전과 신 버전을 호환시키고 싶을 때 사용합니다!
- 레거시 코드를 사용하고 싶지만 새로운 인터페이스가 레거시 코드와 호환되지 않을 때
- 이미 만든 것을 재사용하고자 하나 이 재사용 가능한 라이브러리를 수정할 수 없을 때
- 이미 만들어진 클래스를 새로운 인터페이스(API)에 맞게 개조할때
패턴 장점
- 새로운 인터페이스와 데이터 변환부분을 분리할 수 있기 때문에 SRP을 만족합니다.
- 기존 클래스 코드를 건들지 않고 클라이언트 인터페이스를 새로 만들어서 어댑터와 작동하기 때문에 OCP를 만족합니다.
- 만약 버그가 발생해도 기존의 클래스에는 버그가 없으므로 Adapter 역할의 클래스를 중점적으로 조사하면 되므로 버그 수정에도 용이합니다.
패턴 단점
- 새로운 인터페이스와 어댑터 클래스 세트를 도입했을 때의 복잡도가 직접 서비스(Adaptee) 클래스를 변경하는 것의 복잡도보다 클 수도 있습니다.
참고
'CS > Design Pattern' 카테고리의 다른 글
옵서버 패턴 (Observer Pattern) (0) | 2024.04.18 |
---|---|
싱글톤 패턴 (Singleton Pattern) (0) | 2024.04.18 |
브리지 패턴 (Bridge Pattern) (0) | 2024.04.17 |
컴포지트 패턴 (Composite Pattern) (0) | 2024.04.17 |
퍼싸드 패턴 (Facade Pattern) (0) | 2024.04.17 |