본문 바로가기

Develop/DESIGN PATTERNS

[GoF Design Pattern] 어댑터 패턴 (Adapter pattern)

1. 어댑터 패턴이란?

기존 코드를 클라이언트가 사용하는 인터페이스의 구현체로 바꿔주는 패턴이다. (구조적인 패턴)

따라서 인터페이스를 따르지 않는 기존 코드를 재사용할 수 있게 된다.

이때 클라이언트는 Target 인터페이스만 사용하면 된다.

2. 구현 방법

다음과 같은 구조를 가져갈 수 있다.

 

위 그림을 살펴보면 클라이언트는 UserDetails, UserDetailService를 사용하고자 한다.

하지만 해당 서비스에서 실제 제공하는 클래스는 Account, AccountService이다. 따라서 이 간극을 메꿔줄 Adapter가 필요하다.

여기서는 AccountUserDetails, AccountUserDetails가 그 역할을 한다!

AccountService accountService = new AccountService();
UserDetailsService userDetailsService = new AccountUserDetailsService(accountService);
LoginHandler loginHandler = new LoginHandler(userDetailsService);
String login = loginHandler.login("id", "password");

이제 클라이언트는 위 코드를 작성할 수 있다.

public class Account implements UserDetails{

    @Override
    public String getUsername() {
        return this.name;
    }

    @Override
    public String getPassword() {
        return this.password;
    }
}

만약 우리가 코드를 직접 수정할 수 있다면, Adapter 클래스를 만들지 않고 Adaptee에 해당하는 클래스에서 직접 구현해도 된다.

다만 이렇게 되면 해당 클래스가 Target 인터페이스에 종속된다는 단점이 있다.

따라서 상황에 따라 적절한 선택을 하면 된다 :)

3. 장/단점

1) 장점

기존 코드는 유지한 채로, 우리가 원하는 인터페이스(Target interface)에 맞춘 형태로 구현체를 만들어서 재사용할 수 있다. (SRP)

또한 기존 코드가 하던 일과 특정 인터페이스 구현체로 변환하는 작업을 각기 다른 클래스로 분리하여 관리할 수 있다. (OCP)

2) 단점

Adapter 클래스가 생기기 때문에 복잡도가 늘어날 수 있다.

따라서 기존 코드가 인터페이스를 직접 구현하도록 변경할 수 있다면 조금 더 실용적으로 어댑터 패턴을 적용해볼 수 있다.