어댑터 패턴

hodu·2024년 8월 26일
0

클린아키텍쳐

목록 보기
4/5
post-custom-banner

어댑터 패턴(Adapter Pattern)

호환되지 않는 인터페이스를 가진 클래스들이 함께 동작할 수 있도록 해주는 패턴

class NaverPayment:
    def pay(): ...

class TossPayment:
    def payment(): ...

def process_payment(payment_method, amount):
    if (isinstance(payment_method, NaverPayment)):
        payment_method.pay(amount)
        
    elif (isinstance(payment_method, TossPayment)):
        payment_method.payment(amount)
        
naver_pay = NaverPayment()
toss_pay = TossPayment()

process_payment(naver_pay, 10000)
process_payment(toss_pay, 5000)

어댑터 패턴을 사용하지 않았을 때의 예시.

NaverPayment, TossPayment는 각 paypayment라는 클래스 메서드를 가지고있다. 이 메서드는 결제를 해주는 메서드이며 행동은 같고 이름만 다르다.

만약 다른 결제수단인 KakaoPay가 추가될 경우 process_payment는 또다시 if문을 사용하여 수정해주어야 한다.

이제 어댑터 패턴을 추가해보자

class NaverPayment:
    def pay(): ...

class TossPayment:
    def payment(): ...

class TossAdapter:
    def __init__(self, toss):
        self.toss = toss

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

def process_payment(payment_method, amount):
    payment_method.pay(amount)

naver_pay = NaverPayment()
toss_pay = TossPayment()
toss_adapter = TossAdapter(toss_pay)

process_payment(naver_pay, 10000)
process_payment(toss_adapter, 5000)

TossAdapter에서 pay를 호출하게 되면 payment로 변환해주고 있다.

그래서 process_payment내부에서는 각 payment_method별로 수정하지 않고 pay만을 호출하면 된다.

휴대폰 충전기는 핸드폰과 전원 콘센트 사이에서 연결해주는 변환기의 역할을 한다. 이런식으로 새로운 클래스(휴대폰 충전기)를 만들어 다른 인터페이스(핸드폰-전원콘센트)에 맞게 변환하는 방법을 “어댑터 패턴”이라고 한다.

질문?

  • 이걸 왜 써야하지? TossPayment의 payment 메서드 명을 pay로 바꾸면 되지 않나?

  • (비슷한 질문)DIP을 사용해서 어떤 결제수단이든 상관없게 하면 되는거 아닌가?

    • 외부 라이브러리를 사용하고 있어 메서드명 변경이 어려울 경우
    • 기존에 있던 코드 변경이 다른 곳에 영향을 주게 될 경우(레거시)
    • 더 복잡한 인터페이스 변경이 필요할
    • 기존 시스템 재설계가 어려울 경우

    에 사용하게 된다.

호출당하는 쪽의 메서드를 호출하는 쪽의 코드에서 대응할 수 있도록 중간에 변환기를 두는 패턴

profile
안녕 세계!
post-custom-banner

0개의 댓글