디자인 패턴 - Adapter Pattern

bp.chys·2020년 7월 24일
0

OOP & Design Pattern

목록 보기
17/17

어댑터 패턴

  • 어댑터 패턴은 클라이언트와 서버의 인터페이스가 서로 맞지 않을 경우 이를 연결하기 위해 어댑터 클래스를 구현하는 디자인 패턴이다.
  • 클라이언트가 사용하고 있는 기존의 인터페이스와 서버가 제공하는 인터페이스를 변경하지 않고 둘을 연결할 수 있다는 장점이 있다.

예시

  • Tolr 검색 서버가 제공하는 인터페이스와 클라이언트가 요구하는 인터페이스가 일치하지 않는다.
  • Tolr 검색 서버가 제공하는 데이터의 반환 타입과 클라이언트가 필요하는 데이터의 타입 역시 일치하지 않는다.
  • 중간에서 메서드 호출과 반환 데이터 타입을 일치시켜주는 SearchServiceTolrAdapter 클래스가 필요하다.

public class SearchServiceTolrAdapter implements SearchService {

    private TolrClent tolrClent = new TolrClient();
    
    public SearchResult search(String keyword) {
        TolrQuery tolrQuery = new TolrQuery(keyword);
        QueryResponse response = tolrClient.query(tolrQuery);
        SearchResult result = convertToResult(response);
        return result;
    }
    
    public SearchResult convertToResult(QueryResponse response) {
        List<TolrDocument> tolrDocs = response.getDocumentList().getDocuments();
        List<SearchDocument> docs = new ArrayList<SearchDocument>();
        for (TolrDocument tolrDoc : tolrDocs) {
            docs.add(new SearchDocument(tolrDoc.getId(), ... );
        }
        return new SearchResult(docs);
    }
}

TolrClient를 합성(Composition)으로 사용하고 있지만, 상속하여 query() 메서드를 사용할 수 도 있다. 하지만 이는 만약 클라이언트가 사용하는 SearchService 인터페이스가 추상클래스인 경우 자바에서는 다중상속이 제한된다는 점을 주의해야 한다.

SOLID 관점에서 본 어댑터 패턴

  • 단일 책임 원칙 : 어댑터 클래스로 인해 구현 클래스(어댑티)와 사용 클래스(클라이언트)를 분리할 수 있다.
  • 개방 폐쇄 원칙 : 어댑티(Adaptee)와 함께 그에 맞는 어댑터(Adapter)만 변경한다면 이를 사용하는 클라이언트 코드는 변경될 필요가 없다.
  • 리스코프 치환 원칙 : 어댑터 클래스가 기존의 클라이언트의 인터페이스 메서드를 잘 재정의하고 있다.
  • 인터페이스 분리 원칙 : 어댑터 클래스는 기존에 잘 분리된 인터페이스를 구현(상속)한다.
  • 의존성 역전 원칙 : 어댑터 클래스와 어댑터 클래스를 사용하는 클라이언트 모두 추상화된 인터페이스에 의존하고 있다.

결론

어댑터 패턴은 클라이언트 인터페이스와 서버 모듈의 인터페이스가 서로 다른 경우, 양쪽의 코드를 모두 변경하지 않고 연결시킬 수 있는 디자인 패턴이다. 양쪽에 대한 이해도가 있어야 하기 때문에 비용이 수반되는 패턴이지만 그만큼 OCP도 따르면서 변경에 유연하게 대처할 수 있다는 장점도 누릴 수 있다.

레거시 코드를 리팩토링하거나, 새로운 서버 모듈을 빠르게 도입해야할 경우 유용하게 사용할 수 있는 패턴이다.


참고자료

  • 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴 - 최범균
profile
하루에 한걸음씩, 꾸준히

0개의 댓글