Adapter Pattern

김남건·2021년 7월 31일
0

Design Pattern

목록 보기
2/3
post-thumbnail

Adapter란?

사전적 의미로는 기계, 가구 등을 다목적으로 사용하기 위한 부가 기구를 말한다. 전압이 110V 기구가 있는데, 220V 콘센트에 꽂아 사용하기 위해 110V 어뎁터를 사용하는 것이 대표적인 예시다.

Adapter Pattern이란?

이미 주어진 알고리즘(Adaptee)을 Adapter라는 기능을 통하여 원하는 기능으로 변경하는 것이다. 이렇게만 설명을 하면 너무 추상적으로 느껴질 것이다.

다음 그림에서 우리가 어떤 라이브러리에서 받아온 Adaptee라는 클래스를 사용한다고 가정하자. Adaptee 클래스는 이미 배포된 라이브러리이기 때문에 우리가 코드를 건드릴 수가 없는 상황이다. 그리고 알고리즘을 이용하는 코드는 여러 곳이 있기 때문에 그런 코드들을 하나하나 수정하기에도 곤란한 상황이다.

이런 상황에서 아래 그림과 같이 Adapter 클래스를 만들고, 알고리즘을 알맞게 이용하여 우리가 원하는 기능을 구현하면, 알고리즘의 소스인 Adaptee나 알고리즘을 사용하는 코드들을 수정하지 않고도 기능을 성공적으로 변경할 수 있다.

예시

요구사항

다음 연산을 수행하는 객체를 만들어야 한다. 구현 객체 이름은 Adapter로 한다.

  1. 수의 두 배 값을 반환
  • twiceOf(Float): Float
  1. 수의 반값을 반환
  • halfOf(Float): Float

두 배와 절반을 구하는 함수는 Math 클래스에서 이미 구현되어 있다. 그러나 Double로 구현이 되어 있어 요구사항에 맞지 않는 상황이다.

public class Math {
    //두배
    public static double twoTime(double num) {
        return 2*num;
    }
    //절반
    public static double halfnum(double num) {
        return num/2;
    }
}

구현

Adapter 인터페이스를 선언하여 두 메서드를 선언한다.
(선언과 구현을 분리하기 위해 인터페이스 사용)

public interface Adapter {
    public Float twiceOf(Float f);
    public Float halfOf(Float f);
}

Adapter 인터페이스를 구현하는 AdapterImpl 클래스를 선언하여 기능을 구현한다.

public class AdapterImpl implements Adapter{
    @Override
    public Float twiceOf(Float f) {
        return (float) Math.twoTime(f.doubleValue());
    }

    @Override
    public Float halfOf(Float f) {
        return (float) Math.halfnum(f.doubleValue());
    }
}

다음 코드를 실행하면 정상적으로 동작한다.

public class Main {
    public static void main(String[] args) {
        Adapter adapter = new AdapterImpl();
        System.out.println(adapter.twiceOf(100f));
        System.out.println(adapter.halfOf(88f));
    }
}

추가 요구사항 및 구현

  1. Math 클래스에 새롭게 두 배를 구할 수 있는 함수가 추가되었다. 새로 구현된 알고리즘을 이용하도록 프로그램을 수정해라.
public class Math {
    // ...
    //강화된 알고리즘
    public static Double doubled(Double d) {
        return d*2;
    }
}
  • 강화된 알고리즘을 이용하면 다음과 같이 수정할 수 있다.
public class AdapterImpl implements Adapter{
    @Override
    public Float twiceOf(Float f) {
        return Math.doubled(f.doubleValue()).floatValue();
    }
    
    //...
}
  1. 절반을 구하는 기능에서 로그를 찍는 기능을 추가해라.
  • Math 클래스의 경우 라이브러리로 배포된 상태여서 건드려서는 안된다고 가정하자. 이 상황에서도 역시 AdapterImpl을 수정하면 된다.
public class AdapterImpl implements Adapter{
    // ...
    @Override
    public Float halfOf(Float f) {
        System.out.println("절반 함수 호출"); // 로그 기능 추가
        return (float) Math.halfnum(f.doubleValue());
    }
}

두 개의 요구사항 모두 알고리즘의 소스인 Math 클래스나, 알고리즘을 이용하는 Main 클래스를 수정하지 않고 AdapterImpl만 수정하여 해결할 수 있다.

Reference

https://www.youtube.com/watch?v=gJDZ7pcvlAU&t=732s

0개의 댓글