GoF의 구조패턴으로 분류되었고 클래스의 인터페이스를 클라이언트가 원하는 대로 변경할 수 있는 패턴이다. 어댑터 패턴은 호환 불가능한 인터페이스를 때문에 협력할 수 없는 클래스들을 협력할 수 있게 한다.
1. 다음과 같은 Client와 서비스를 제공하는 Service클래스가 있다고 하자.
class Service {
void service(char[] data) {
System.out.println("Called service");
}
}
public class Client {
public static void main(String[] args) {
String _input="Input Data";
Service service = new Service();
char[] charData = _input.toCharArray();
adapter.request(charData);
}
}
Client를 보면 입력값(_input)을 char[]로 변환하고 Service의 service메소드를 호출한다.
2. 여기서 수정사항이 생기거나 예기치 못한 상황으로 Service클래스가 아닌 다음과 같은 OtherService클래스를 사용한다고 하자.
class OtherService {
void request(List<Character> data) {
System.out.println("Called request");
}
}
3. Service클래스 대신 OtherService를 사용한다면 Client코드는 다음과 같이 바뀌어야 한다.
public class Client {
public static void main(String[] args) {
String _input="Input Data";
OtherService otherservice = new OtherService();
List<Character> charList = new ArrayList<>();
for (char c : _input.toCharArray()) {
charList.add(c);
}
adapter.request(charList);
}
}
Service가 바뀌었을 때 Client의 코드가 바뀌는 상황이다. 이는 Client와 Service사이의 높은 결합이 형성되어 있다는 뜻이다. Service의 함수명이나 매개변수 타입과 같이 작은것들이 바뀌면 Client의 코드에 영향이 미친다는 것이다.
두 개의 클래스 사이에 호환을 담당하는 클래스를 둔다면?
이후 Service를 담당하는 객체가 바뀌어도 Client대신 호환을 담당하는 클래스를 바꾸면 된다!
1. AdapterInterface
interface AdapterInterface {
void request(String data);
}
2. Adapter
class Adapter implements AdapterInterface {
private Adaptee adaptee;
public Adapter(Adaptee a) {
this.adaptee = a;
}
public void request(String data) {
char[] charData = data.toCharArray();
adaptee.specificFunction(charData);
}
}
3. Adaptee
class Adaptee {
void specificFunction(char[] specificdata) {
System.out.println("Called specificFunction");
}
}
Adaptee를 다른 클래스로 교체하거나 char[]를 List로 바꿔도 Adapter의 request()만 수정하면 된다.
즉, Client는 Adaptee의 변경에 아무런 영향을 받지 않는다.
위 코드를 보면 Apdater 클래스에서 adaptee라는 객체를 가지고 있고 함수 호출을 통해 메시지를 전달하는데 이것을 위임이라 한다.
private Adaptee adaptee;