어댑터 패턴
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")
