[7] 디자인패턴: 어댑터 패턴 (Adapter)

2025. 12. 29. 08:50·Java/Design Pattern

1. 들어가며

 소프트웨어 개발 과정에서 우리는 이미 잘 만들어진 외부 라이브러리나 과거에 작성된 유산(Legacy) 코드를 마주하게 된다. 하지만 우리가 새로 설계한 시스템의 인터페이스와 이러한 기존 코드의 인터페이스가 서로 맞지 않는 경우가 빈번히 발생한다. 이때 기존의 코드를 수정하지 않고도 두 인터페이스를 연결하여 함께 작동하게 만드는 것이 바로 어댑터 패턴(Adapter Pattern)인 것이다.

1.1. 어댑터 패턴의 정의와 필요성

 어댑터 패턴은 이름 그대로 우리가 일상에서 사용하는 '변환 젠더'와 같은 역할을 수행한다. 220V 플러그를 110V 콘센트에 꽂기 위해 콘센트를 통째로 뜯어고치는 대신, 그 사이를 이어주는 어댑터를 사용하는 것과 같은 이치이다.

1.2. 왜 어댑터가 필요한가?

 객체지향 설계 원칙 중 하나인 OCP(개방-폐쇄 원칙)에 따르면, 확장에는 열려 있어야 하고 수정에는 닫혀 있어야 한다. 만약 새로운 라이브러리를 도입할 때마다 기존의 우리 시스템 코드를 수정해야 한다면 이는 설계의 결함으로 이어진다. 어댑터 패턴은 기존 코드(수정 불가능하거나 수정하기 곤란한 코드)를 그대로 유지하면서 새로운 요구사항이나 인터페이스에 맞춰 변환해주는 가교 역할을 수행하는 것이다.


2. 어댑터 패턴의 구조

어댑터 패턴은 크게 세 가지 주요 구성 요소로 나뉜다.

  1. 타겟 (Target): 클라이언트가 직접적으로 사용하고자 하는 인터페이스이다. 우리 시스템의 표준 규격이라고 볼 수 있다.
  2. 어댑티 (Adaptee): 아직 우리 시스템과 호환되지 않는 실제 기능을 가진 기존의 클래스나 외부 라이브러리이다.
  3. 어댑터 (Adapter): 타겟 인터페이스를 구현하며, 내부에서 어댑티의 메서드를 호출하여 클라이언트의 요청을 어댑티가 이해할 수 있는 방식으로 변환한다.

3. 스프링 부트로 구현하는 어댑터 패턴

실무에서 가장 흔히 겪는 사례인 '외부 SMS 발송 라이브러리 통합'을 예로 들어본다. 우리 시스템은 MessageService라는 표준 인터페이스를 사용하고 있는데, 새로 계약한 'A사'의 라이브러리는 메서드 명과 파라미터가 완전히 다르다고 가정한다.

3.1. 타겟 인터페이스 정의

우리 시스템이 기대하는 표준 인터페이스이다.

public interface MessageService {
    void sendMessage(String text, String phoneNumber);
}

3.2. 어댑티(Adaptee): 외부 라이브러리

우리가 수정할 수 없는 외부 업체의 클래스이다. 메서드 명이 sendSms이고 파라미터 순서도 다르다.

// 우리가 수정할 수 없는 외부 라이브러리 코드라고 가정한다.
public class ExternalSmsLibrary {
    public void sendSms(String phone, String content) {
        System.out.println("외부 라이브러리 작동 - 수신번호: " + phone + ", 내용: " + content);
    }
}

3.3. 어댑터(Adapter) 구현

외부 라이브러리를 감싸서 우리 시스템의 인터페이스에 맞게 변환해준다.

@Component
public class SmsServiceAdapter implements MessageService {

    private final ExternalSmsLibrary externalLibrary;

    public SmsServiceAdapter() {
        // 실제로는 빈 주입이나 생성자 생성을 통해 관리한다.
        this.externalLibrary = new ExternalSmsLibrary();
    }

    @Override
    public void sendMessage(String text, String phoneNumber) {
        // 우리 시스템의 호출 방식을 외부 라이브러리의 방식에 맞춰 변환하여 전달한다.
        externalLibrary.sendSms(phoneNumber, text);
    }
}

4. 스프링 실무에서의 어댑터 패턴 활용

스프링 프레임워크는 그 자체가 거대한 어댑터들의 집합체라고 해도 과언이 아니다.

4.1. HandlerAdapter (Spring MVC)

 Spring MVC에서 가장 중요한 어댑터 사례이다. 스프링은 @Controller 뿐만 아니라 과거 방식의 인터페이스 기반 컨트롤러, 심지어 일반 서블릿까지도 지원해야 한다. DispatcherServlet은 이 다양한 핸들러들을 일일이 알 수 없으므로, 중간에 HandlerAdapter를 두어 일관된 방식으로 이들을 호출하는 것이다.

4.2. Spring Security의 Configurer

 과거에 자주 쓰였던 WebSecurityConfigurerAdapter 또한 어댑터 패턴의 한 종류이다. 복잡한 보안 설정을 우리가 필요한 부분만 오버라이딩하여 사용할 수 있도록 미리 구조를 잡아둔 어댑터 역할을 수행했다. (현재는 컴포넌트 기반 설정으로 바뀌었지만, 개념적 이해에 도움을 준다.)


5. 실무적 이점과 주의사항

5.1. 장점

  • 기존 코드 보존: 검증된 기존 코드나 외부 라이브러리를 수정하지 않고 재사용할 수 있다.
  • 결합도 감소: 클라이언트는 인터페이스(Target)만 알면 되므로 어댑티의 구체적인 구현 변경에 영향을 받지 않는다.
  • 유연한 확장: 새로운 업체나 라이브러리가 추가되어도 새로운 어댑터만 작성하면 기존 로직은 그대로 유지된다.

5.2. 주의사항 (Over-engineering)

 단순히 메서드 이름 하나가 다른 정도라면 어댑터를 만들기보다 직접 호출하는 것이 나을 수도 있다. 하지만 인터페이스가 복잡하게 얽혀 있고, 향후 교체 가능성이 있는 핵심 외부 연동 모듈이라면 어댑터 패턴을 도입하는 것이 장기적으로 훨씬 유리한 것이다.

 

'Java > Design Pattern' 카테고리의 다른 글

[9] 디자인패턴: 옵저버 패턴 (Observer)  (0) 2025.12.29
[8] 디자인패턴: 퍼사드 패턴 (Facade)  (0) 2025.12.29
[6] 디자인패턴: 팩토리 패턴 (Factory)  (0) 2025.12.29
[5] 디자인패턴: 데코레이터 패턴 (Decorator)  (0) 2025.12.29
[4] 디자인패턴: 프록시 패턴 (Proxy)  (0) 2025.12.29
'Java/Design Pattern' 카테고리의 다른 글
  • [9] 디자인패턴: 옵저버 패턴 (Observer)
  • [8] 디자인패턴: 퍼사드 패턴 (Facade)
  • [6] 디자인패턴: 팩토리 패턴 (Factory)
  • [5] 디자인패턴: 데코레이터 패턴 (Decorator)
h6bro
h6bro
백엔드 개발자의 기술 블로그
  • h6bro
    Jun's Tech Blog
    h6bro
  • 전체
    오늘
    어제
    • 분류 전체보기 (250) N
      • Java (18)
        • Core (9)
        • Design Pattern (9)
      • Spring (80)
        • Core (24)
        • MVC (6)
        • DB (10)
        • JPA (26)
        • Monitoring (3)
        • Security (11)
        • WebSocket (0)
      • Database (33)
        • Redis (15)
        • MySQL (18)
      • MSA (25) N
        • MSA 기본 (11)
        • MSA 아키텍처 (14) N
      • Kafka (30)
        • Core (18)
        • Connect (12)
      • ElasticSearch (11)
        • Search (11)
        • Logging (0)
      • Test (4)
        • k6 (4)
      • Docker (9)
      • CI&CD (10)
        • GitHub Actions (6)
        • ArgoCD (4)
      • Kubernetes (18)
        • Core (12)
        • Ops (6)
      • Cloud Engineering (4)
        • AWS Infrastructure (3)
        • AWS EKS (1)
        • Terraform (0)
      • Project (8)
        • LinkFolio (1)
        • Secondhand Market (7)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • Cloud Engineering 포스팅 정리
  • 인기 글

  • 태그

    ㅈ
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
h6bro
[7] 디자인패턴: 어댑터 패턴 (Adapter)
상단으로

티스토리툴바