여기서 전략 패턴의 컨텍스트를 템플릿이라 부르고, 익명 내부 클래스로 만들어지는 오브젝트를 콜백이라고 부른다.
전략 패턴과 동일한가? -> 거의 모든 것이 동일하나, 전략을 익명 내부 클래스로 정의해서 사용하는 것에서 차이가 있다.
주로 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("활");
}
}