Computer Science/Design Pattern

[Design Pattern] 어댑터 패턴 (Adapter Pattern)

dbssk 2023. 9. 22. 00:42

어댑터 패턴(Adapter Pattern)

  • 호환되지 않는 인터페이스들을 연결하는 디자인 패턴
  • 주요 구성 요소
    • 타겟(Target) : 클라이언트가 사용하려는 새로운 인터페이스
    • 어댑티(Adaptee) : 아직 호환되지 않은 기존 클래스/인터페이스
    • 어댑터(Adapter) : 타켓 인터페이스를 구현하여 클라이언트 요청을 어댑티로 전달하는 클래스
    • 클라이언트(Client) : 특정 작업을 요청하는 클래스

  • 용도 및 필요성
    • 기존 코드나 라이브러리를 수정하지 않고 새로운 인터페이스를 사용해야 할 때
    • 다른 곳에서 개발한 클래스를 현재 시스템에 통합해야 할 때
    • 이미 존재하는 클래스를 새로운 인터페이스로 감싸서 사용자가 편리하게 이용할 수 있도록 할 때

  • 사용 방법
    • 상속(extends)을 이용한 클래스 어댑터 패턴
    • 객체(composition)을 이용한 객체 어댑터 패턴

  • 장점
    • 기존 코드(Adaptee)를 변경하지 않고 원하는 인터페이스(Target)를 구현하는 객체를 만들어 재사용이 가능 → 개방-폐쇄 원칙(OCP) 준수
    • 기존 코드와 인터페이스 변환 작업을 분리하여 관리 가능 → 단일 책임 원칙(SRP) 준수

  • 단점
    • 클래스 수가 증가하고 구조가 복잡해질 수 있다.

 

객체 어댑터 패턴

// 고래 인터페이스
public interface Whale {
    void swim();
    void communicate();
}

// 돌고래 인터페이스
public interface Dolphin {
    void swim();
    void speak();
}

// 고래 객체
public class BlueWhale implements Whale {
    @Override
    public void swim() {
        System.out.println("Blue whale swims gracefully.");
    }

    @Override
    public void communicate() {
        System.out.println("Blue whale communicates with low-frequency sounds.");
    }
}

// 어댑터: 돌고래를 고래로 변환
public class DolphinAdapter implements Whale {
    private Dolphin dolphin;

    public DolphinAdapter(Dolphin dolphin) {
        this.dolphin = dolphin;
    }

    @Override
    public void swim() {
        dolphin.swim();
    }

    @Override
    public void communicate() {
        dolphin.speak();
    }
}

// 클라이언트 코드
public class AdapterExample {
    public static void main(String[] args) {
        // 고래 객체 사용
        Whale blueWhale = new BlueWhale();
        blueWhale.swim();
        blueWhale.communicate();

        System.out.println("-----");

        // 돌고래 어댑터를 사용하여 돌고래 객체를 고래로 변환하여 사용
        Dolphin dolphin = new Dolphin() {
            @Override
            public void swim() {
                System.out.println("Dolphin swims playfully.");
            }

            @Override
            public void speak() {
                System.out.println("Dolphin speaks in high-pitched clicks.");
            }
        };

        Whale dolphinAdapter = new DolphinAdapter(dolphin);
        dolphinAdapter.swim();
        dolphinAdapter.communicate();
    }
}
// 결과
Blue whale swims gracefully.
Blue whale communicates with low-frequency sounds.
-----
Dolphin swims playfully.
Dolphin speaks in high-pitched clicks.

 

클래스 어댑터 패턴

Java에서 클래스 어댑터 패턴을 구현하기 위해 다중 상속이 필요하므로 주로 객체 어댑터 패턴이 사용되며 C++과 같이 다중 상속을 지원하는 프로그래밍 언어에서만 구현할 수 있다.

// 고래 인터페이스
public interface Whale {
    void swim();
    void communicate();
}

// 돌고래 인터페이스
public interface Dolphin {
    void swim();
    void speak();
}

// 고래 객체
public class BlueWhale implements Whale {
    @Override
    public void swim() {
        System.out.println("Blue whale swims gracefully.");
    }

    @Override
    public void communicate() {
        System.out.println("Blue whale communicates with low-frequency sounds.");
    }
}

// 돌고래 어댑터 클래스 (클래스 어댑터 패턴)
public class DolphinAdapter extends BlueWhale implements Dolphin {
    @Override
    public void speak() {
        System.out.println("Dolphin speaks in high-pitched clicks.");
    }
}

// 클라이언트 코드
public class AdapterExample {
    public static void main(String[] args) {
        // 고래 객체 사용
        Whale blueWhale = new BlueWhale();
        blueWhale.swim();
        blueWhale.communicate();

        System.out.println("-----");

        // 돌고래 어댑터 클래스를 사용하여 돌고래 객체를 고래로 변환하여 사용
        Dolphin dolphin = new DolphinAdapter();
        dolphin.swim();
        dolphin.speak();
    }
}

 

[참고] https://www.geeksforgeeks.org/adapter-pattern/