어댑터 패턴

IT 위키

Adapter Pattern; Wrapper Pattern

호환되지 않는 인터페이스를 가진 클래스들이 함께 동작할 수 있도록, 한쪽의 인터페이스를 다른 쪽이 기대하는 형태로 변환해 주는 GoF 구조 패턴

기존 클래스를 수정하지 않고 재사용하고 싶은데 인터페이스가 맞지 않을 때 사용한다. 전압이나 플러그 모양이 다른 기기를 쓰기 위한 변환 어댑터에 비유된다.

구성 요소

[편집 | 원본 편집]
역할 설명
Target 클라이언트가 사용하는 인터페이스. 클라이언트가 호출하는 쪽이다
Adapter Target 인터페이스를 구현하면서, 내부적으로 Adaptee 를 호출해 변환을 수행한다
Adaptee 이미 존재하지만 인터페이스가 맞지 않는 클래스. 실제 기능을 가진 쪽이다
Client Target 인터페이스를 통해 기능을 사용하는 주체

호출 흐름은 Client → Target → Adapter → Adaptee 순이다. 즉 클라이언트에 가까운 쪽이 Target, 기존 코드에 가까운 쪽이 Adaptee 다.

구현 방식

[편집 | 원본 편집]
  • 클래스 어댑터: 상속으로 Adaptee 를 확장한다. 다중 상속이 필요해 언어의 제약을 받는다.
  • 객체 어댑터: 위임(composition)으로 Adapter 가 Adaptee 인스턴스를 멤버로 가진다. 실무에서 주로 쓰인다.

파이썬 코드 예제

[편집 | 원본 편집]
  # Adaptee - 이미 존재하는 클래스. 인터페이스가 맞지 않는다
  class LegacyPrinter:
      def print_text(self, text):
          print("Legacy:", text)

  # Target - 클라이언트가 기대하는 인터페이스
  class Printer:
      def send(self, text):
          raise NotImplementedError

  # Adapter - Target 을 구현하면서 내부에서 Adaptee 를 호출
  class PrinterAdapter(Printer):
      def __init__(self, legacy):
          self.legacy = legacy
      def send(self, text):
          self.legacy.print_text(text)

  # Client 는 Target 인터페이스만 알면 된다
  printer = PrinterAdapter(LegacyPrinter())
  printer.send("hello")

같이 보기

[편집 | 원본 편집]