어댑터 패턴(Adapter Pattern)은 호환성 문제를 해결하기 위한 디자인 패턴으로, 두 개의 호환되지 않는 인터페이스나 클래스를 연결하여 함께 사용할 수 있게 만들어줍니다.
이 패턴은 기존 코드를 수정하지 않고 새로운 환경에서 사용할 수 있도록 하는 데 매우 유용합니다.
어댑터 패턴은 이미 만들어져 있는 클래스나 라이브러리를 우리 시스템에 맞게 변환하여 사용할 때 유용합니다. 어댑터를 사용하면, 기존 시스템의 코드 변경 없이 외부 코드나 다른 규격의 코드를 우리 시스템에 맞게 사용할 수 있게 됩니다.
abstract public class Animal {
abstract String getName();
}
public class OuterRabbit {
private String fullname = "토끼";
public String getFullname() {
return fullname;
}
}
만약 OuterRabbit과 같은 손댈 수 없는 외부 라이브러리 코드가 있다고 한다면
추상클래스인 Animal을 우리 마음대로 OuterRabbit에 extends 할 수 없기 때문에
getName을 직접 사용할 수 없다.
그럼에도 저 fullname을 사용하고 싶다. getFullname()을 어댑터를 사용해서 사용할 수 있게 해보자
public class RabbitAdapter extends Animal {
private OuterRabbit rabbit;
public RabbitAdapter(OuterRabbit rabbit) {
this.rabbit = rabbit;
}
@Override
String getName() {
return rabbit.getFullname();
}
}
public class App {
public static void main(String[] args) {
Doorman d1 = new Doorman();
Mouse m1 = new Mouse();
d1.쫓아내(m1);
RabbitAdapter rabbit = new RabbitAdapter(new OuterRabbit());
d1.쫓아내(rabbit);
}
}
Animal 추상 클래스와 호환되지 않는 OuterRabbit객체를 호환되게 하기 위해서 RabbitAdapter가 Animal을 상속받고 OuterRabbit을 멤버변수에 넣고 생성자에서 OuterRabbit 객체를 주입했습니다.
즉 Animal 상속을 통해 RabbitAdapter에 우리가 필요한 기능인 getName()을 상속 받았고 우리가 변경할 수 없는 OuterRabbit을 멤버변수로 생성자에서 주입 받고 어댑터가 감싼 것.
getName() 메서드에서는 OuterRabbit의 getFullname() 메서드를 호출하여 이름을 반환합니다. 이를 통해 Animal 추상 클래스와 호환되지 않는 OuterRabbit 클래스를 사용할 수 있게 되었습니다.
멤버변수로 받았으므로 RabbitAdapter 내부에서 OuterRabbit을 사용해서 getName() { return rabbit.getFullname(); } 으로 OuterRabbit의 이름을 구할 수 있게 됐다. 호환성 완료
RabbitAdapter는 Animal을 상속받았으므로 Animal 타입으로 사용될 수 있으며, 내부적으로 OuterRabbit 객체의 메서드를 호출합니다.
어댑터는 시스템에서 요구하는 인터페이스에 맞게 외부 객체를 변환하는 역할을 하므로, 이름은 RabbitAdapter이지만 Animal로 간주할 수 있습니다.
이는 어댑터 패턴의 핵심으로, 호환성 문제를 해결하고 코드의 유연성과 재사용성을 높이는 데 중요한 역할을 합니다.
Share article