티스토리 뷰

반응형

어댑터 패턴

 호환되지 않는 모양의 인터페이스를 사용하고 싶을 때에는 어댑터 패턴의 어댑터를 이용해 클라이언트가 요구하는 모양의 다른 인터페이스로 변환하여 사용할 수 있습니다. 어댑터는 인터페이스가 호환되지 않아 함께 쓸 수 없었던 클래스를 사용할 수 있도록 도와줍니다. 클라이언트는 인터페이스를 사용하면서도 중간에 어댑터가 있다는 사실을 알지 못합니다.

 

 

출처: 돼지코 플러그 변환 아답터 110V-220V, 인터파크

 

 

구조

출처: https://refactoring.guru/ko/design-patterns/adapter

1. Client: 서비스 인터페이스를 사용하는 고객입니다.

2. Client Interface: Client가 사용하는 서비스들의 공통 로직(틀)을 의미합니다.

3. Adapter: Service를 Client가 사용할 수 있는 Client Interface 형식으로 변환합니다.

4. Service: Client가 사용하고자 하는 타사의 호환되지 않는 서비스입니다.

 

 


예제

Turkey 클래스를 Duck 인터페이스처럼 사용할 수 있도록 도와주는 TurkeyAdapter를 만들어봅시다.

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

 

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

public class WileTurkey implements Turkey {
    public void gobble() {
        System.out.println("골골");
    }
    
    public void fly() {
        System.out.println("짧은 거리를 날고 있어요!");
    }
}

 

현재 Duck과 Turkey는 서로 다른 인터페이스로 구현되어 있기 때문에 Turkey 인스턴스를 Duck 인터페이스처럼 사용하지 못합니다. Duck을 상속하는 TurkeyAdapter 클래스를 만들어, Turkey를 Duck 인스턴스처럼 사용할 수 있도록 변환해보겠습니다.

 

public class TurkeyAdapter implements Duck {
    Turkey turkey;
    
    public TurkeyAdapter(Turkey turkey) {
        this.turkey = turkey;
    }
    
    public void quack() {
        turkey.gobble();
    }
    
    public void fly() {
        // 칠면조가 오리처럼 멀리 날기 위해 fly 메소드를 5번 실행
        for(int i = 0; i < 5; i++) {
            turkey.fly();
        }
    }
}

 

 

public class DuckTestDrive {
    public static void main(String[] args) {
        Turkey turkey = new WildTurkey();
        Duck turkeyAdapter = new TurkeyAdapter(turkey);
        
        testDuck(turkeyAdapter);
    }
    
    static void testDuck(Duck duck) {
        duck.quack();
        duck.fly();
    }

 

이제 TurkeyAdapter를 사용하면 칠면조도 오리처럼 꽥꽥거리고, 날 수 있습니다..... 😎

위와 같은 어댑터 패턴 구현 방법을 객체 어댑터라고 부릅니다.

 

 

 

객체 어댑터

 

객체 어댑터 구조

 

객체 어댑터의 장점

- 구성을 사용하기 때문에 어댑티 클래스와 그 어댑티의 서브클래스에 대해서도 어댑터 역할을 할 수 있습니다.

- 코드량이 줄어들고 유연성이 증가합니다.

- 어댑터에 행동을 추가하면 어댑티 클래스와 모든 서브 클래스에 새 행동이 적용됩니다.

 

 

 

 

클래스 어댑터

 구성을 사용하는 객체 어댑터와 달리 클래스 어댑터는 타깃과 어댑티를 모두 서브클래스로 만들어 사용합니다.

클래스 어댑터 패턴은 다중 상속이 필요한데, 자바에서는 다중 상속이 불가능해서 구현을 할 수 없다고 하네요.

 

클래스 어댑터 구조

클래스 어댑터의 장점

- 특정 어댑티 클래스에만 어댑터를 적용할 수 있습니다.

- 어댑티 전체를 다시 구현하지 않아도 됩니다.

- 서브클래스이기 때문에 어댑티의 행동을 오버라이드 할 수 있습니다.

 

 

반응형