본문 바로가기

ComputerScience/DesignPattern

[DesignPattern] Adapter Pattern

어댑터 패턴(Adapter Pattern)

어댑터 패턴은 특정 클래스 인터페이스를 클라이언트에서 요구하는 다른 인터페이스로 변환합니다.
이로써 인터페이스가 호환되지 않아 같이 쓸 수 없었던 클래스를 사용할 수 있게됩니다.

 

이미지 출처: https://en.wikipedia.org/wiki/Adapter_pattern

위의 UML Class Diagram에서, Target 인터페이스를 필요로 하는 Client 클래스는 Adaptee 클래스의 인터페이스가 Target 인터페이스와 일치하지 않기 때문에 Adaptee 클래스를 직접 재사용할 수 없습니다. 대신 클라이언트는 Adapter 클래스를 통해 작업하며, 이 Adapter 클래스는 Adaptee를 사용하여 Target 인터페이스를 구현합니다.

객체 어댑터 방식은 런타임에 어댑티 객체에 위임함으로써(Adaptee.specificOperation()) Target 인터페이스를 구현합니다. 

 

반면, 클래스 어댑터 방식은 컴파일 타임에 Adaptee 클래스를 상속함으로써(specificOperation()) Target 인터페이스를 구현합니다.

즉, 어댑터 디자인 패턴은 클라이언트와 어댑티 간의 인터페이스 불일치 문제를 해결하기 위해 어댑터 클래스를 도입합니다.

 이 어댑터 클래스는 클라이언트가 Adaptee와 공통된 Target 인터페이스를 통해 상호 작용할 수 있도록 보장합니다.

이는 위임을 통한 방식(객체 어댑터)이나 상속을 통한 방식(클래스 어댑터)으로 구현됩니다.

 

아래는 예시입니다.

 

우리는 Turkey(칠면조) 객체를 만들고 싶은데, Duck 인터페이스를 구현하려고 합니다.

그런데 quack이 아닌 gobble이라는 칠면조 특유의 울음소리로 바꾸고 싶습니다.

이럴때 TurkeyAdapter를 사용합니다.

 

Target: Duck

public interface Duck {
    public void quack();
    public void fly();
}

 

 

Adapter : TurkeyAdapter

public class TurkeyAdapter implements Duck {

    // Target Interface를 상속하고 있기 때문에 클라이언트에서 호환 가능하다.
    // Adaptee를 구성하여 Target Interface의 기능을 Adaptee의 기능으로 구현한다.
    Turkey turkey;

    public TurkeyAdapter(Turkey turkey) {
        this.turkey = turkey;
    }

    @Override
    public void quack() {
        turkey.gobble();
    }

    @Override
    public void fly() {
        for (int i = 0; i < 5; i++) {
            turkey.fly();
        }
    }
}

 

Adaptee: Turkey

public interface Turkey {
    public void gobble();
    public void fly();
}

 

Turkey: WildTurkey

public class WildTurkey implements Turkey 
{ 
    public void gobble() {
    	System.out.println(“Gobble gobble”);
    } 
    public void fly() {
    	System.out.println(“I’m flying a short distance”); 
    }
}

 

Client: Main

public class DuckTestDrive {
    public static void main(String[] args) {
        Duck duck = new MallardDuck();

        Turkey turkey = new WildTurkey();
        Duck turkeyAdapter = new TurkeyAdapter(turkey);

        System.out.println("The Turkey says...");
        turkey.gobble();
        turkey.fly();

        System.out.println("\nThe Duck says...");
        testDuck(duck);

        System.out.println("\nThe TurkeyAdapter says...");
        testDuck(turkeyAdapter);

    }

    static void testDuck(Duck duck) {
        duck.quack();
        duck.fly();
    }
}

참고자료

https://en.wikipedia.org/wiki/Adapter_pattern

 

Adapter pattern - Wikipedia

From Wikipedia, the free encyclopedia Design pattern in computer programming In software engineering, the adapter pattern is a software design pattern (also known as wrapper, an alternative naming shared with the decorator pattern) that allows the interfac

en.wikipedia.org

https://github.com/IT-Book-Organization/HeadFirst-DesignPattern/blob/main/Chapter_07/README.md