Java에서 어댑터 패턴(Adapter Pattern)은 객체 지향 디자인 패턴 중 하나로, 서로 호환되지 않는 인터페이스를 가진 두 개의 클래스를 함께 동작할 수 있도록 중간에 "어댑터"라는 클래스를 두어 호환성을 제공하는 패턴입니다. 이 패턴은 기존 클래스를 수정하지 않고, 기존 코드에 새로운 기능을 추가하거나, 기존 코드와 새로운 코드 간의 호환성을 유지하는 데 유용합니다.
어댑터 패턴의 주요 구성 요소는 다음과 같습니다:
- 타겟 인터페이스(Target Interface): 클라이언트가 사용하는 인터페이스입니다. 클라이언트는 이 인터페이스를 통해 어댑터에 접근합니다.
- 어댑티(Adaptee): 기존 클래스 또는 호환되지 않는 인터페이스를 가진 클래스입니다. 이 클래스는 클라이언트가 필요로 하는 기능을 제공하지만, 클라이언트가 사용하는 인터페이스와 호환되지 않습니다.
- 어댑터(Adapter): 어댑터 패턴의 핵심 클래스입니다. 어댑티의 인터페이스를 타겟 인터페이스로 변환하여, 클라이언트가 어댑티를 사용할 수 있도록 합니다. 어댑터는 타겟 인터페이스를 구현하고, 어댑티의 객체를 참조하여 실제 작업을 수행합니다.
- 클라이언트(Client): 타겟 인터페이스를 사용하여 어댑터를 호출하는 클래스입니다. 클라이언트는 어댑터가 어댑티와 호환되지 않는다는 사실을 알 필요가 없습니다.
예제 코드
아래는 간단한 어댑터 패턴의 예제를 보여줍니다.
// 1. 타겟 인터페이스
interface Target {
void request();
}
// 2. 어댑티 클래스 (호환되지 않는 인터페이스)
class Adaptee {
public void specificRequest() {
System.out.println("Adaptee의 specificRequest 호출");
}
}
// 3. 어댑터 클래스
class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
// Adaptee의 specificRequest를 타겟 인터페이스의 request로 변환
adaptee.specificRequest();
}
}
// 4. 클라이언트 코드
public class Client {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target adapter = new Adapter(adaptee);
// 클라이언트는 타겟 인터페이스를 사용하여 어댑터를 호출
adapter.request(); // "Adaptee의 specificRequest 호출" 출력
}
}
실행 결과
Adaptee의 specificRequest 호출
동작 방식
- 클라이언트는
Target
인터페이스를 통해Adapter
를 호출합니다.
Adapter
는 내부적으로Adaptee
객체를 가지고 있으며, 클라이언트의 호출을 받아Adaptee
의 메서드를 호출합니다.
- 결과적으로, 클라이언트는
Adaptee
의 메서드가 호출된다는 것을 알 필요 없이,Target
인터페이스를 통해Adaptee
의 기능을 사용할 수 있게 됩니다.
사용 사례
어댑터 패턴은 다음과 같은 경우에 유용합니다:
- 기존 클래스를 변경하지 않고, 새로운 인터페이스를 추가해야 할 때.
- 서로 호환되지 않는 인터페이스를 가진 클래스들을 함께 사용할 때.
- 기존 클래스의 인터페이스를 수정할 수 없거나, 수정하는 것이 비효율적일 때.
이 패턴을 사용하면 시스템의 유연성과 확장성을 높일 수 있으며, 기존 코드와 새로운 코드 간의 통합을 용이하게 합니다.
Share article