새로운 업체에서 제공한 클래스 라이브러리를 사용하려고 했는데, 기존 시스템에서 사용하는 인터페이스가 다른 상황임.
업체에서 제공받은 클래스를 변경할 수 없는 상태임.
새로운 업체에서 사용하는 인터페이스를 기존에 사용하던 인터페이스에 적응시켜 주는 클래스를 만들면 됨. → 어댑터
어댑터 사용 방법 알아보기
public interface Duck {
public void quack();
public void fly();
}
public class MallardDuck implements Duck {
public void quack() {
System.out.println("꽥");
}
public void fly() {
System.out.println("날고 있어요!!");
}
}
오리는 꽥꽥 거리고, 날 수 있음.
public interface Turkey {
public void gobble();
public void fly();
}
public class WildTurkey implements Turkey {
public void gobble() {
System.out.println("골골");
}
public void fly() {
System.out.println("짧은 거리를 날고 있어요!");
}
}
칠면조는 꽥꽥거리지 않고, 골골 거림.
날 수는 있지만, 멀리 날지 못함
Duck 객체를 못쓰고, Turkey 객체를 대신 사용해야 한다면, 인터페이스가 다르기에 Turkey 객체를 바로 사용할 수 없음.
어댑터를 만들어야 함.
public class TurkeyAdapter implements Duck {
Turkey turkey;
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
public void quack() {
turkey.gobble();
}
public void fly() {
for (int i = 0; i < 5; i++) {
turkey.fly();
}
}
}
우선, 적응시킬 형식의 인터페이스를 구현해야 함.
클라이언트에서 원하는 인터페이스를 구현해야 함.
기존 형식 객체의 레퍼런스가 필요함.
인터페이스에 들어있는 메소드를 모두 구현한다.
오리 어댑터 테스트
p276 참고
어댑터 패턴 알아보기
클라이언트
타깃 인터페이스에 맞게 구현되어 있음.
어댑터
타깃 인터페이스를 구현함.
어댑티 인스턴스가 들어있음.
클라이언트에서 어댑터를 사용하는 방법
클라이언트에서 타깃 인터페이스로 메소드를 호출해서 어댑터에 요청을 보냄
어댑터는 어댑티 인터페이스로 요청을 어댑티에 관한 메소드 호출로 변환함.
클라이언트는 호출 결과를 박지만, 중간에 어댑터가 있는 사실은 모름.
어댑터 패턴의 정의
📍 어댑터 패턴(Adapter Pattern) : 특정 클래스 인터페이스를 클라이언트에서 요구하는 다른 인터페이스로 변환함. 인터페이스가 호환되지 않아 같이 쓸 수 없었던 클래스를 사용할 수 있게 도와줌.
인터페이스를 변환해 주는 어댑터를 만들면 호환되지 않는 인터페이스를 사용하는 클라이언트를 그대로 활용할 수 있음.
클라이언트와 구현된 인터페이스를 분리할 수 있음.
변경 내역이 어댑터에 캡슐화되기에 나중에 인터페이스가 바뀌더라도 클라이언트를 바꿀 필요가 없음.