개발블로그

[디자인패턴] 어댑터 패턴 본문

STUDY/CS

[디자인패턴] 어댑터 패턴

devmel 2026. 9. 4. 14:12
Contents 접기
 

개념

 

필요성

프로그램을 만들다 보면 이미 존재하는 코드와 새로 사용해야 하는 코드의 형식이 맞지 않는 경우가 있음.

=> 기존 코드가 기대하는 방식과 새로 연결할 객체의 방식이 다를 때, 중간에서 맞춰줄 수 없을까?

 

ex)

결제 객체가 pay(amount)라는 메서드를 제공

payment.pay(10000)

 

그런데 새로 연동해야 하는 외부 결제 API는 다른 이름과 다른 형식의 메서드를 제공 할 수 있음

external_payment.request_payment(price=10000)

 

기능은 비슷함 (둘 다 결제를 처리)

BUT 사용하는 방식이 다르기 때문에 기존 코드에서는 바로 사용할 수 없음.

 

해결방법 => 외부 API를 기존 코드 형식에 맞게 감싸기 

 

 

의미

어댑터 패턴은 서로 맞지 않는 인터페이스를 중간에서 변환해 연결하는 패턴

=> 기존 코드는 익숙한 방식 그대로 사용할 수 있음.

 

 

핵심 구조

구성 요소 역할 예시
Client 기존 인터페이스를 사용하는 코드 주문 서비스
Target Interface Client가 기대하는 인터페이스 pay(amount)
Adaptee 실제 연결해야 하는 기존 객체 또는 외부 API 외부 결제 API
Adapter Target Interface에 맞게 Adaptee를 감싸는 객체 결제 어댑터

 

=> 외부 API나 기존 코드 자체를 억지로 바꾸는 것이 아니라, 

중간에 어댑터를 두어, 서로 다른 사용 방식을 맞춰주는 것.

 

 


 

예시

 

EX]

주문로직 : 결제 객체가 apy(amount) 메서드를 제공한다고 가정

class OrderService:
    def __init__(self, payment):
        self.payment = payment

    def order(self, amount):
        return self.payment.pay(amount)

이 구조에서 OrderService는 구체적인 결제 방식이 무엇인지 알 필요가 없음. 

그저 pay(amount)를 호출할 수 있으면 됨

class CardPayment:
    def pay(self, amount):
        return "카드 결제"

 

그런데 새로 연동해야 하는 외부 결제 API는 다른 형식을 사용한다고 할 때 

class ExternalPaymentAPI:
    def request_payment(self, price):
        return f"{price}원 외부 결제 요청"

기능은 결제지만, 메서드 이름이 pay()가 아니라 request_payment()다. 

파라미터 이름도 amount가 아니라 price

=> 이 상태에서는 OrderService에 바로 넣을 수 없음

external_payment = ExternalPaymentAPI()
order_service = OrderService(external_payment)

order_service.order(10000)

OrderService는 내부에서 self.payment.pay(amount)를 호출한다.
하지만 ExternalPaymentAPI에는 pay()가 없기 때문에 오류가 발생

 

이 문제를 해결하기 위해 어댑터로 인터페이스 변환

class ExternalPaymentAdapter:
    def __init__(self, external_payment):
        self.external_payment = external_payment

    def pay(self, amount):
        return self.external_payment.request_payment(price=amount)

=> 외부 API를 내부 코드가 기대하는 pay(amount) 형태로 바꿔줌

 

이제 OrderService는 수정하지 않아도 됨

external_payment = ExternalPaymentAPI()
payment = ExternalPaymentAdapter(external_payment)

order_service = OrderService(payment)
print(order_service.order(10000))

 

실행흐름)

OrderService.order(10000)
→ payment.pay(10000)
→ ExternalPaymentAdapter.pay(10000)
→ ExternalPaymentAPI.request_payment(price=10000)

 

구분 역할
OrderService pay(amount)를 기대하는 기존 코드
ExternalPaymentAPI request_payment(price)를 제공하는 외부 API
ExternalPaymentAdapter pay(amount) 호출을 request_payment(price) 호출로 변환

 

 

 


 

장점

장점

장점 설명
기존 코드 변경 최소화 기존 코드가 기대하는 인터페이스를 유지한 채 새로운 객체를 연결할 수 있다.
외부 구현과 내부 코드 분리 외부 API의 메서드 이름이나 응답 구조를 내부 코드가 직접 알 필요가 줄어든다.
호환성 확보 서로 다른 인터페이스를 가진 객체들을 같은 방식으로 사용할 수 있다.
변경 영향 축소 외부 API 형식이 바뀌어도 어댑터만 수정하면 되는 구조를 만들 수 있다.
일관된 사용 방식 제공 내부 코드에서는 여러 외부 객체를 동일한 인터페이스로 다룰 수 있다.

 

 

효과적인 상황

상황 이유
외부 API를 연동해야 하는 경우 외부 API 형식을 내부 코드에 맞게 감쌀 수 있다.
기존 코드를 크게 바꾸기 어려운 경우 기존 인터페이스를 유지하면서 새 구현을 연결할 수 있다.
서로 다른 라이브러리를 같은 방식으로 사용하고 싶은 경우 어댑터를 통해 일관된 사용 방식을 제공할 수 있다.
외부 변경 영향을 줄이고 싶은 경우 변경 지점을 어댑터로 제한할 수 있다.

 

 


 

주의점

 

어댑터는 기존 코드와 외부 코드 사이의 형식 차이를 흡수한다. 

하지만 두 코드의 개념이나 책임이 근본적으로 다르다면 단순히 메서드 이름만 맞춘다고 좋은 구조가 되지는 않음.

 

ex)

외부 API의 request_payment()가 실제로는 결제 요청뿐 아니라 포인트 적립, 알림 발송, 정산 요청까지 함께 처리한다고 할 때 

class ExternalPaymentAPI:
    def request_payment(self, price):
        process_payment(price)
        add_point(price)
        send_notification(price)
        create_settlement(price)

이 API를 단순히 pay(amount)로 감싸면 겉으로는 결제 인터페이스처럼 보임

class ExternalPaymentAdapter:
    def pay(self, amount):
        return self.external_payment.request_payment(price=amount)

하지만 내부적으로는 결제 외의 여러 작업까지 함께 실행된다.

이 경우 pay()라는 이름만 보고 사용하는 코드는 실제로 어떤 부작용이 발생하는지 알기 어려움.

 

주의점 설명
의미 차이를 숨기지 않기 메서드 이름만 맞추고 실제 동작 의미가 다르면 오해가 생길 수 있다.
어댑터 비대화 변환 로직이 너무 많아지면 어댑터가 복잡해질 수 있다.
오류 처리 방식 차이 외부 API의 예외, 실패 응답, 재시도 정책을 내부 기준에 맞게 정리해야 한다.
성능 비용 변환 과정이 많아지면 불필요한 처리 비용이 생길 수 있다.
책임 범위 확인 어댑터가 단순 변환을 넘어 비즈니스 로직까지 담당하지 않도록 주의해야 한다.

 

'STUDY > CS' 카테고리의 다른 글

[디자인패턴] 싱글톤 패턴  (0) 2026.09.04
[디자인패턴] 데코레이터 패턴  (0) 2026.09.04
[디자인패턴] 옵저버 패턴  (0) 2026.09.04
[디자인패턴] 팩토리 패턴  (1) 2026.09.04
[디자인 패턴] 전략패턴  (0) 2026.09.04