클래스의 인터페이스를 사용자가 원하는 인터페이스 형태로 변환시킨다.
서로 일치하지 않는 인터페이스를 갖는 클래스들을 함께 동작시킨다.
사용처
기존 클래스를 사용하고 싶지만 해당 인터페이스가 나머지 코드와 호환하지 않는 경우
Service를 변경할 수 없을 때.
장단점
다양한 형식으로 데이터를 변환할 수 있다.
다양한 인터페이스를 가진 객체간의 협업을 도와준다
구현
Client : 프로그램의 기존 비즈니스 로직을 포함하는 클래스
Client Interface : 다른 클래스가 클라이언트 코드와 협력할 수 있도록 따라야 하는 프로토콜
Service : 클라이언트와 호환되지 않는 다른 클래스
Adapter : 클라이언트와 서비스에서 잘동할 수 있는 클래스. 서비스 객체를 래핑하고, 클라이언트를 구현한다.
Note : 클라이언트는 한 어댑터와 구체적인 결합을 하지 않는다. 따라서 기존 클라이언트 코드를 변경하지 않고 새로운 어댑터 클래스를 생성할 수 있다.
코드
Service
interface Turkey{
void gobble();
void fly();
}
Client Interface
//오리와 칠면조의 인터페이스가 다름을 주목하자
interface Duck{
void quack();
void fly();
}
Adapter
class TurkeyAdapter implements Duck{
Turkey turkey;
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
@Override
public void quack() {
turkey.gobble();
}
@Override
public void fly() {
turkey.fly();
}
}
TurkeyAdapter에서 Turkey를 Duck처럼 사용하고 있다!
Client
class MallardDuck implements Duck {
@Override
public void quack() {
System.out.println("quack");
}
@Override
public void fly() {
System.out.println("flying");
}
가장 좋은 방법은 누락된 기능을 adapter 내부에서 누락된 기능이 있는 객체를 래핑하여 필요한 기능을 동적으로 얻는 것이다. 이 기능을 사용하려면 대상 클래스들의 공통 인터페이스가 있어야하고, 어댑터의 필드가 해당 인터페이스를 implements해야 한다. → Decorator와 매우 유사하다.