orderService
의 핵심 기능은 주문 로직이다. 메서드 단위로 보면 orderService.orderItem(
)의 핵심 기능은 주문 데이터를 저장하기 위해 리포지토리를 호출하는 orderRepository.save(itemId)
코드가 핵심 기능이다.GOF 디자인 패턴에서는 템플릿 메서드 패턴을 다음과 같이 정의했다.
템플릿 메서드 디자인 패턴의 목적은 다음과 같습니다. “작업에서 알고리즘의 골격을 정의하고 일부 단계를 하위 클래스로 연기합니다. 템플릿 메서드를 사용하면 하위 클래스가 알고리즘의 구조를 변경하지 않고도 알고리즘의 특정 단계를 재정의할 수 있습니다.” [GOF]
하지만
extends
다음에 바로 부모 클래스가 코드 상에 지정되어 있다. 따라서 부모 클래스의 기능을 사용하든 사용하지 않든 간에 부모 클래스를 강하게 의존하게 된다.템플릿 메서드 패턴과 비슷한 역할을 하면서 상속의 단점을 제거할 수 있는 디자인 패턴이 바로 전략 패턴 (Strategy Pattern)이다
전략 패턴은 변하지 않는 부분을 Context라는 곳에 두고, 변하는 부분을 Strategy라는 인터페이스를 만들고 해당 인터페이스를 구현하도록 해서 문제를 해결한다. 상속이 아니라 위임으로 문제를 해결하는 것이다.
전략 패턴에서 Context 는 변하지 않는 템플릿 역할을 하고, Strategy 는 변하는 알고리즘 역할을 한다.
GOF 디자인 패턴에서 정의한 전략 패턴의 의도는 다음과 같다.
알고리즘 제품군을 정의하고 각각을 캡슐화하여 상호 교환 가능하게 만들자. 전략을 사용하면 알고리즘을 사용하는 클라이언트와 독립적으로 알고리즘을 변경할 수 있다.
쉽게 이야기해서 컨텍스트(문맥)는 크게 변하지 않지만, 그 문맥 속에서 strategy를 통해 일부 전략이 변경된다 생각하면 된다.
public class ContextV1 {
private final Strategy strategy;
public ContextV1(Strategy strategy) {
this.strategy = strategy;
}
public void execute() {
long startTime = System.currentTimeMillis();
// 비즈니스 로직 실행
strategy.call();
// 비즈니스 로직 죵로
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("resultTime={}", resultTime);
}
}
ContextV1
의 내부 필드에 Strategy를 두고 사용하는 부분이다.ContextV1
와 Strategy를 실행 전에 원하는 모양으로 조립해두고, 그 다음에 ContextV1
를 실행하는 선 조립, 후 실행 방식에서 매우 유용하다.public class ContextV2 {
public void execute(Strategy strategy) {
long startTime = System.currentTimeMillis();
// 비즈니스 로직 실행
strategy.call();
// 비즈니스 로직 죵로
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("resultTime={}", resultTime);
}
}
다른 코드의 인수로서 넘겨주는 실행 가능한 코드를 콜백(callback)이라 한다.
콜백 정의 프로그래밍에서 콜백(callback) 또는 콜애프터 함수(call-after function)는 다른 코드의 인수로서 넘겨주는 실행 가능한 코드를 말한다. 콜백을 넘겨받는 코드는 이 콜백을 필요에 따라 즉시 실행할 수도 있고, 아니면 나중에 실행할 수도 있다. (위키백과 참고)
쉽게 이야기해서 callback 은 코드가 호출( call )은 되는데 코드를 넘겨준 곳의 뒤( back )에서 실행된다는 뜻이다.
ContextV2
예제에서 콜백은 Strategy이다.ContextV2.execute(..)
를 실행할 때 Strategy를 넘겨주고, ContextV2
뒤에서 Strategy 가 실행된다.ContextV2
와 같은 방식의 전략 패턴을 템플릿 콜백 패턴이라 한다.JdbcTemplate
, RestTemplate
, TransactionTemplate
, RedisTemplate
처럼 다양한 템플릿 콜백 패턴이 사용된다. 스프링에서 이름에 XxxTemplate
가 있다면 템플릿 콜백 패턴으로 만들어져 있다 생각하면 된다.