모르지 않다는 것은 아는것과 다르다.

Books

템플릿 콜백 패턴 (토비의 스프링 3장)

채마스 2022. 2. 28. 20:08

Template Callback Pattern

  • 전략 패턴의 변형이다.
  • 정확히는 전략을 익명 내부 클래스로 구현한 전략 패턴이라고 할 수 있다.
  • 스프링 3대 프로그래밍 모델 중 하나인 DI 에서 사용하는 특별한 형태의 전략 패턴이다.
  • 여기서 전략 패턴의 컨텍스트를 템플릿이라 부르고, 익명 내부 클래스로 만들어지는 오브젝트를 콜백이라고 부른다.
  • 전략 패턴과 동일한가? -> 거의 모든 것이 동일하나, 전략을 익명 내부 클래스로 정의해서 사용하는 것에서 차이가 있다.
  • 주로 try/catch/finally 블록을 사용하는 코드에 사용된다.





동작 흐름

  • 클라이언트의 역할은 콜백 오브젝트를 만들고, 콜백이 참조할 정보를 제공한다.
  • 만들어진 콜백은 클라이언트가 템플릿의 메소드를 호출할 때 파라미터로 전달된다.
  • 템플릿은 내부에서 생성한 참조정보를 갖고 콜백 오브젝트의 메소드 호출한다.
  • 콜백은 클라이언트 메소드에 있는 정보와 템플릿이 제공한 참조정보를 이용해 작업을 수행한다.
  • 작업을 마친후 다시 템플릿에 반환한다.
  • 템플릿은 콜백이 돌려준 정보를 사용해서 작업을 마저 수행한다.
  • 최종 결과에 따라 클라이언트에 다시 반환한다.





코드 예시

  • 아래와 같은 코드가 있다고 해보자.
public class Client {

    public static void main(String[] args) {
        전략 strategy = null;
        군인 rambo = new 군인();

        strategy = new 총();
        rambo.runContext(strategy);

        strategy = new 칼();
        rambo.runContext(strategy);

        strategy = new 활();
        rambo.runContext(strategy);
    }
}
  • 위의 코드는 익명 내부 클래스를 이용해서 아래와 같이 바뀔 수 있다.


public class Client {

    public static void main(String[] args) {
        군인 rambo = new 군인();

        rambo.runContext(new 전략() {
            @Override
            public void runStrategy() {
                System.out.println("총 : 빵야");
            }
        });

        rambo.runContext(new 전략() {
            @Override
            public void runStrategy() {
                System.out.println("칼 : 슈욱");
            }
        });

                rambo.runContext(new 전략() {
            @Override
            public void runStrategy() {
                System.out.println("활 : 슈슉");
            }
        });

    }
}
  • 위의 코드는 중복된 부분이 많다.
  • 위의 코드는 아래와 같이 리팩토링할 수 있다.


public class 군인 {

    void runContext(String weaponSound) {
        System.out.println("전투 시작");
        executeWeapon(weaponSound).runStrategy();
        System.out.println("전투 종료");
    }

    private 전략 executeWeapon(final String weaponSound) {
        return new 전략() {
            @Override
            public void runStrategy() {
                System.out.println(weaponSound);
            }
        };
    }
}

public class Client {

    public static void main(String[] args) {
        군인 rambo = new 군인();

        rambo.runContext("총");
        rambo.runContext("칼");
        rambo.runContext("활");

    }
}
  • 위의 코드를 보면 전략이 군인 내부로 들어온 것을 확인할 수 있다.
  • 스프링은 이와 같은 형식으로 템플릿 콜백 패턴을 DI에 적용시켰다.




REFERENCES