어댑터 패턴
📌 정의
호환되지 않는 인터페이스를 갖는 두 클래스를 함께 동작할 수 있도록 하는 구조적인 패턴이다. 다른 시스템이나 라이브러리 등에서 제공하는 인터페이스와 애플리케이션의 요구사항에 맞지 않는 인터페이스 사이에 중간 어댑터를 두어 상호 동작 가능하게 만든다.
❗️특징
- Target 은 변화에 대한 요구사항이다.
- Adaptee 는 기존의 코드이다.
- Adapter 는 변화에 대한 요구사항을 구현한 새로운 코드이다.
Adaptee 가 가지고 있는 기능을 Adapter 가 주입받아 operation() 을 구현한다.
Client 는 인터페이스인 Target 을 통해 이를 사용할 수 있게 된다.
✍ 예시 코드
1) Target Interface (대상 인터페이스): 클라이언트가 기대하는 인터페이스를 정의
class Target {
request() {
return '기대하는 인터페이스';
}
}
2) Adaptee (적응자): 기존에 사용 중인 클래스 또는 라이브러리를 나타낸다.
class Adaptee {
specificRequest() {
return '적응자의 메서드';
}
}
3) Class Adapter (클래스 어댑터): 어댑터 클래스가 대상 인터페이스를 구현하면서 동시에 기존 클래스(Adaptee)를 상속받는다.
class Adapter extends Adaptee {
request() {
return this.specificRequest();
}
}
4) Object Adapter (객체 어댑터): 어댑터 클래스가 대상 인터페이스를 구현하고, 기존 클래스(Adaptee)의 인스턴스를 포함(컴포지션)하여 사용한다.
class Adapter {
constructor(adaptee) {
this.adaptee = adaptee;
}
request() {
return this.adaptee.specificRequest();
}
}
5) 인터페이스를 호출
const targetClassAdapter = new Adapter();
console.log(targetClassAdapter.request());
const adaptee = new Adaptee();
const targetObjectAdapter = new Adapter(adaptee);
console.log(targetObjectAdapter.request());
❗️어댑터 패턴을 사용하면, 클라이언트는 Target 인터페이스를 통해 기대하는 메서드를 호출할 수 있으며, 어댑터가 이를 실제로 구현하는 형태이다.