[Design Pattern] Adapter Pattern

윰진·2023년 10월 28일
0

면접

목록 보기
11/11

Reference

📢 공부한 내용을 바탕으로 작성하였습니다. 내용에 문제가 있다면 댓글 또는 메일 jnw__@naver.com 주시면 확인 후 빠른 수정하겠습니다. !

어댑터 패턴(Adapter Pattern)` :
인터페이스가 다른 두 클래스를 하나의 인터페이스로 변환시켜주는 구조적인 디자인 패턴

  • 특정 클래스 인터페이스를 클라이언트에서 요구하는 다른 인터페이스로 변환
    {\rightarrow} 인터페이스가 호환되지 않아 같이 쓸 수 없었던 클래스를 사용할 수 있게 해줌

객체지향 기본 원칙

  • 변경되는 부분은 캡슐화한다.
  • 상속보다는 구성을 활용한다.
  • 구현보다는 인터페이스에 맞춰서 프로그래밍한다.
  • 클래스는 확장에는 열려 있어야 하지만 변경에는 닫혀있어야 한다.
  • 최소 지식 원칙(Principle of Least Knowledge)
    • 객체 사이의

01. 어댑터 패턴

어댑터 패턴
{\rightarrow} 제공된 시스템의 구조가 기존 것과 다르더라도 유연하게 적용할 수 있음

기존 코드

  • 오리 객체를 테스트하는 코드가 구현되어 있음
from abc import ABC, abstractmethod

class Quackable(ABC):
    @abstractmethod
    def quack(self) -> None:
        pass

    @abstractmethod
    def fly(self) -> None:
        pass

class Duck(Quackable):
   
   def quack(self)->None:
       print("꽥")
       
   def fly(self)->None:
       print("날고 있어요.")
       
class TestDuck:
   
   def test(self, duck:Quackable)->None:
       duck.quack()
       duck.fly()

my_duck = Duck()
test_obj = TestDuck()
my_duck.test(my_duck)

"""
꽥
날고 있어요
"""

상황 : 칠면조 등 다른 가금류들을 구현해야 해서 외주를 맡겼는데 같은 역할을 하는 함수의 이름이 다름

  • 구현된 클래스의 함수명 등을 직접 수정할 수 없다면, 어떻게 해야할까?

전달받은 칠면조 클래스

  • 우는 소리를 내는 함수의 이름이 gooble
  • fly를 호출했을 때 duck보다 짧은 거리를 날음
class Turkey:
    
    def gooble(self)->None:
        print("골골")
    
    def fly(self)->None:
        print("짧은 거리를 날고 있어요!")

{\rightarrow} TestDuck 클래스로 Turkey를 테스트하고 싶을 때, 어댑터 패턴을 사용해보자!

class TurkeyAdapter(Quackable):

    def __init__(self, turkey:Turkey):
        self.turkey = turkey
        
    def quack(self):
        self.turkey.gooble()
        
    def fly(self):
        # 오리가 나는 거리만큼 날 수 있도록 다섯 번 호출해줌 
        for dist in range(5):
            self.turkey.fly()

테스트 코드

my_duck = Duck()
my_turkey = Turkey()
test_obj = TestDuck()
my_duck.test(my_duck)
my_duck.test(my_turkey)

"""
꽉
날고 있어요
골골
짧은 거리를 날고 있어요
짧은 거리를 날고 있어요
짧은 거리를 날고 있어요
짧은 거리를 날고 있어요
짧은 거리를 날고 있어요
"""

참고

  • 상기 예제 코드는 객체 구성(composition)을 사용

  • 다중 상속을 사용하는 클래스 어댑터 방식도 있음

    • class TurkeyAdapter(Quackable, Turkey):
          # 클래스 어댑터 방식
          def quack(self)->None:
             self.gooble()
          
          def fly(self)->None:
              for dist in range(5):
                  self.fly()
      
       my_duck = Duck()
       my_turkey_adapter = TurkeyAdapter()
      
       test_obj = TestDuck()
       test_obj.test(my_duck)
       test_obj.test(my_turkey_adapter)

객체 합성 (Object Composition):

장점단점
유연성과 확장성더 많은 코드 작성 필요
런타임에 동적인 변경 가능
클래스 계층 구조의 낮은 결합도

클래스 어댑터 (Class Adapter):

장점단점
상속을 이용한 코드 재사용다중 상속 제한 (일부 언어에서)
구조의 명시성유연성 감소 (정적인 디자인)

0개의 댓글