어댑터 패턴 Adapter Pattern

어댑터 패턴

  • 데이터 타입을 변경하는 패턴
  • 라이브러리나 프레임워크 등 외부 코드를 바로 사용하지 않는다. 외부 코드는 지정한 인터페이스에 맞춰 구현하고, 내부코드는 해당 구현체를 사용한다. 내부 코드와 외부 코드 간 의존성을 최소화 한다.
  • 데이터 타입을 강제하여 일관된 인터페이스를 제공할 때도 사용한다. List, Object[], Map 등 다양한 집합 구조를 Iterator 인터페이스로 관계를 맺을 수 있다.

image

원칙적인 어댑터 패턴의 적용과 어려움

  • 외부 라이브러리나 프레임워크에 의존적이지 않은 코드는 좋은 코드다.
  • 다만, 코드의 양이 많아지고 성능 문제가 발생한다.
  • 인터페이스에 맞춰 의미 없는 래핑이 반복될 수 있다.
  • SRP와 편의성 두 개에서 트레이드 오프가 존재한다.

데코레이터 vs 어댑터 vs 파사드

  • 데코레이터 : 변환되기 전의 데이터 타입과 변환 후의 데이터 타입이 동일하다.
  • 파서드 : 여러 데이터 타입이나 객체 생성이 복잡한 하나의 데이터 타입을, 단순한 API를 가진 하나의 데이터 타입으로 제공한다.
  • 어댑터 : 여러 종류의 데이터 타입을 하나의 데이터 타입으로 통일한다.

어댑터 패턴의 적용 사례

  • HandlerAdapter 등 스프링의 다양한 어댑터 패턴
  • String#valueOf()는 기본 타입 대부분과 char[] 배열, 객체를 파라미터로 받는다. 일관되게 String으로 리턴한다. java.util.Arrays#asList(T…), java.util.Collections#list(Enumeration) 등 다양한 메서드가 존재한다.

참조

  • 백기선, 디자인 패턴 강의(https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4)
  • O’Reilly, “헤드 퍼스트 디자인 패턴”