어댑터 패턴이란?

- 클래스의 인터페이스를 클라이언트가 원하는 형태의 또 다른 인터페이스로 변환하는 패턴

- 어댑터는 호환되지 않는 인터페이스 때문에 동작하지 않는 클래스들을 함께 동작할 수 있도록 만들어준다.

 

전기 플러그를 생각해보자. 미국의 플러그 모양은 110V (11자 모형)이다. 미국 전자 제품을 한국에서 쓰려면 어댑터를 사용하여 한국의 플러그 모양에 맞게 변환해서 사용하면 된다. 이 것이 어댑터 패턴의 기본 원리라고 생각하면 된다.

 

헤드 퍼스트 디자인 책의 예시를 통해 문제점과 해결 방안을 살펴보자.

 

문제점

오리에 대한 Duck 인터페이스와 그를 구현한 MallardDuck, 칠면조에 대한 Turkey 인터페이스와 그를 구현한 WildTurkey 클래스가 존재한다. 오리쇼를 하고 싶은데 오리의 숫자가 부족하여 칠면조를 오리의 탈을 씌워 쇼에 참가해야 하는 상황이다. 먼저 클래스와 인터페이스를 살펴보자.

Duck

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

MallardDuck

public class MallardDuck implements Duck{
    @Override
    public void quack() {
        System.out.println("Quack");
    }

    @Override
    public void fly() {
        System.out.println("I'm flying");
    }
}

Turkey

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

}

WildTurkey

public class WildTurkey implements Turkey{

    // Turkey 인터페이스와 Duck 인터페이스는 다른 인터페이스다.
    // 문제점 : Duck 객체가 부족하여 Turkey 객체도 Duck 객체처럼 사용하고 싶다.
    // TurkeyAdapter를 사용하여 Turkey 객체도 Duck 객체로 변환하여 사용해보자.
    @Override
    public void gobble() {
        System.out.println("Gobble gobble");
    }

    @Override
    public void fly() {
        System.out.println("I'm flying a short distance");
    }
}

 

해결책

어댑터 패턴을 적용하여 Turkey 객체를 Duck "처럼" 사용해보자.

TurkeyAdapter

public class TurkeyAdapter implements Duck{
    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();
        }

    }
}

- Turkey 객체를 생성자의 매개 변수로 받아 Turkey의 매소드를 적절하게 Duck의 메소드에 활용한다.

 

+ Recent posts