티스토리 뷰

어댑터 패턴이란?

어댑터 패턴은 서로 호환되지 않는 인터페이스를 가진 객체들이 협력할 수 있도록 하는 패턴으로, 래퍼로도 불립니다. 기존에 사용했던 시스템(레거시 시스템)을 원하는 인터페이스로 사용가능하게 합니다. 

 

어댑터 패턴의 사용 방법

클래스 어댑터 (상속)

  • 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) 클래스를 변경하는 것의 복잡도보다 클 수도 있습니다.

참고

 

💠 어댑터(Adaptor) 패턴 - 완벽 마스터하기

Adaptor Pattern 어댑터 패턴(Adaptor Pattern) 이란 이름 그대로 클래스를 어댑터로서 사용되는 구조 패턴이다. 어댑터는 우리 주변에도 많이 볼 수 있는 것으로서, 대표적으로 110V 전용 가전제품에 220V

inpa.tistory.com

 

 

'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