본문 바로가기

CS/DesignPattern

(DesignPattern) 어댑터 패턴

어댑터란?
사전적 의미) 기계 기구 등을 다목적으로 사용하기 위한 부가 기구
프로그래밍적 의미) 이미주 어진 알고리즘을 Adapter를 이용해 원하는 기능으로 변경

 

알고리즘을 요구사항에 맞게 변경하여 사용할 수 있다는 것이 POINT!


구현

요구사항

두 수에 대한 다음 연산을 수행하는 객체를 생성

  • 수의 *2의 수를 반환 
  • 수의 1/2의 수를 반환

Math 클래스에서 위의 알고리즘은 이미 구현되어 있다.

 

 

위에 언급하였듯이 Math 클래스에는 두배를 곱하고 2로 나누는 알고리즘이 이미 구현되어있다.

public class Math {
    /*Double*/
    public  static double twoTime(double num) {
        return num*2;
    }
    /*Half*/
    public static double half(double num) {
        return num/2;
    }
}

 

이때 반환 타입이 double이라는 점에 주목하자!

 

고객의 요구사항으로 해당 알고리즘에 대한 반환 타입을 float으로 변환하여야 한다.

 

이때 코드를 직접 수정하지 않기 위해서 어댑터 패턴을 이용한다.

 

float을 반환하는 인터페이스 생성

public interface Adapter {
    /*원하는 기능*/
    public float twiceOf(Float f);
    /*원하는 기능*/
    public float halfOf(Float f);
}

 

해당 인터페이스를 구현하고 기존에 만들었던 Math의 메서드를 호출하여 해당 요구사항에 맞게 변환시킨다.

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.half(f.doubleValue());
    }
}

출력 결과


추가 요구사항

Math 클래스에 새롭게 두 배를 구하는 함수가 추가되었다.

  • 새로 구현된 알고리즘을 이용하도록 프로그램을 수정

절반을 구하는 기능에서 로그 찍는 기능을 추가

 

 

새로 구현된 두배를 구하는 함수 

    @Override
    public float twiceOf(Float f) {

//        return (float) Math.twoTime(f.doubleValue());
        return Math.doubled(f.doubleValue()).floatValue();
    }

이와 같이 구현 메서드에서 간편하게 바꾸기만 하면 된다.

 

 

똑같이 구현 메서드에서 로그 찍는 기능 추가

    @Override
    public float halfOf(Float f) {
        System.out.println("[Log] 절반 함수 호출");
        
        return (float) Math.half(f.doubleValue());
    }

 

실행 결과


정리를 하자면 기존의 프로세스가 있는 경우 큰 틀을 바꾸지 않고 수정하고 싶을 때 유사한 인터페이스를 하나 생성하여

끼워 넣는 패턴을 의미한다.

 

위의 예시가 조금 부족한 것 같아 한 개의 예제를 하나 더 가져오며 설명을 마치고자 한다.

 

기존의 인터페이스

public interface Movable {
	double getSpeed();
}

기존의 인터페이스를 구현하는 클래스

public class BmwCar implements Movable{

	@Override
	public double getSpeed() {
		// TODO Auto-generated method stub
		return 256;
	}

}

기존의 로직을 건들지 않고 수정하고 싶을 때 유사한 인터페이스를 추가

 

유사 인터페이스

public interface MovableAdapter {
	double getSpeed();
}

유사 인터페이스의 구현 클래스 생성

public class MovableAdapterImpl implements MovableAdapter{
	
	private Movable luxuryCar;
	
	public void setLuxuryCar(Movable luxuryCar) {
		this.luxuryCar = luxuryCar;
	}

	@Override
	public double getSpeed() {
		// TODO Auto-generated method stub
		return converMPHtoKMPH(luxuryCar.getSpeed());
	}
	
	private double converMPHtoKMPH(double mph) {
		return mph*1.60934;
	}

}

Main 클래스

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Movable mv = new BmwCar();
		System.out.println(mv.getSpeed());
		
		
		//mv = new MovableAdapterImpl();
		MovableAdapter mva = new MovableAdapterImpl();
		((MovableAdapterImpl) mva).setLuxuryCar(new BmwCar());
		System.out.println(mva.getSpeed());
	}

}

Code Link

https://github.com/mike6321/PURE_JAVA/tree/master/EffectiveStudy

 

mike6321/PURE_JAVA

Contribute to mike6321/PURE_JAVA development by creating an account on GitHub.

github.com

References