'ADAPTER'에 해당되는 글 1건

  1. 2007/09/08 어댑터 ( Adapter ) 패턴
Languages/Design Pattern2007/09/08 11:27
사용자 삽입 이미지

객체 어댑터 패턴


어댑터 패턴 (adapter pattern)은 패턴 중에서도 가장 단순한 것들 중 하나입니다. UML 다이어그램을 보면 그 의미가 비교적 명료하게 파악되는, 쉬운 패턴이기도 하죠.

일련의 메소드들(위의 다이어그램에는 methodB() 하나만 명시되어 있습니다만)을 가진, 이미 구현되어 있는 클래스 Adaptee가 있다고  합시다. Client에서는 Adaptee에 구현되어 있는 기능을 이용하려고 합니다. 그런데 문제는, Client조차도 이미 구현이 끝나있는 상태라는 것이죠. 다음의 코드를 봅시다.

class Client {
    private SomeInterface worker;

    public Client( SomeInterface iObj ) {
        worker = iObj;
    }

    public void doWork() {
        worker.methodA();
    }
}

위의 코드에 따르면, Client는 SomeInterface라는 인터페이스에 따라 구현된 객체의 methodA()를 호출함으로써 자신의 doWork() 함수를 구현합니다. 이 코드는 이미 구현이 끝난 상태라서 더 이상 변경을 할 수 없습니다. 그런데 공교롭게도, Adaptee 클래스는 이 인터페이스에 따라 구현이 된 클래스가 아닙니다. 그러므로 Adaptee 클래스에 의해 만들어진 객체는 Client 클래스의 생성자의 인자로 전달이 될 수가 없고, 따라서 Client 클래스에 의해 만들어진 객체들은 Adaptee 클래스에 의해 만들어진 객체들과는 연동을 할 수 없습니다.

그런데 Adaptee 클래스의 methodB가 사실상 인터페이스 SomeInterface가 요구하는 메소드 methodA()와 동일한 역할을 하는 것이라고 가정한다면, 이런 문제는 Adapter 클래스를 도입함으로써 간단하게 해결이 될 수가 있습니다.

class Adapter implements SomeInterface {
    private Adaptee adaptee;

    public Adapter(Adaptee aObj) {
        adaptee = aObj;
    }

    public void methodA() {
        adaptee.methodB();
    }
}

어떻습니까? 이런 클래스가 있다면, Client와 Adaptee는 다음과 같이 연동이 가능합니다.

Adaptee a = new Adaptee();
...

Adapter adapter = new Adapter(a);
Client client = new Client( adapter );
client.doWork();          // doWork calls methodA of object 'adapter', and it calls methodB of object 'a'

간단하죠? Adapter 패턴은 이처럼 아주 간단한 패턴입니다. 여기( http://en.wikipedia.org/wiki/Adapter_pattern )에 방문하시면 Adapter 패턴에 대한 다른 예제들도 볼 수 있으니 참고하세요. (사실 위의 UML 다이어그램도 거기서 가져온겁니다 -_-;;)

그런데, 꼭 이런 구현 방법밖에는 없는 걸까요? 이렇게 하면 어때요?

class Adapter extends Adaptee implements SomeInterface {
    ...
    public void methodA() {
        super.methodB();
    }
    ...
}

이렇게 하면 Client 쪽에서는 그냥 다음과 같이 해버리면 되죠.

Adapter adapter = new Adapter();
Client client = new Client( adapter );
client.doWork();

어댑터 패턴을 이렇게 구현할 경우, 우리는 이것을 '클래스 어댑터 패턴'이라고 부릅니다. 종전의 구현방식은 '객체 어댑터 패턴'이라고 하고요.


사용자 삽입 이미지

클래스 어댑터 패턴



클래스 어댑터 패턴의 UML 다이어그램은 위와 같습니다. 그런데 이 다이어그램을 자세히 보니, Adaptor에서 Adaptee 클래스들로 이어지는 선들이 전부 'inheritance' (혹은 generalization) 관계를 따르고 있군요. 결국 '다중 상속 (multiple inheritance)'이 가능해야 클래스 어댑터 패턴을 쓸 수 있다는 이야기가 되겠네요.

앞선 예제는 SomeInterface가 '클래스'가 아닌 '인터페이스' 였기 때문에, 다중 상속을 지원하지 않는 Java에서도 클래스 어댑터 패턴을 흉내낼 수 있었습니다. 하지만 SomeInterface가 '인터페이스'가 아닌 '클래스'라면 이야기는 다르죠. Java로는 더 이상 클래스 어댑터 패턴을 구현할 수 없습니다. (꼼수를 좀 부리면 가능할지도 모르죠 :-P) C++는 다중 상속을 지원하기 때문에 당연히 가능합니다.

지금까지 어댑터 패턴에 대해서 살펴보았습니다. 단순한 패턴이라 이해도 어렵지 않고, 더 설명할 것도 없어보이는 군요. 나중에 빼먹고 언급하지 않은 이슈가 있다면, 수정해서 보충하겠습니다. :-)



Posted by 이병준

TRACKBACK http://www.buggymind.com/trackback/32 관련글 쓰기

댓글을 달아 주세요