이번 글에서는 스프링 내부 구현에서 템플릿 메서드 패턴과 전략 패턴이 어떻게 사용되고 있는지 살펴보고, 각각이 선택된 이유를 내 뇌피셜과 함께 정리해보려 한다.
이를 통해 실제 코드를 작성할 때 “템플릿 메서드를 쓸까”, “전략 패턴을 쓸까” 와 같은 고민의 지점을 구조화하고, 결과적으로 유지보수성이 더 높은 방향으로 설계할 수 있는 기준을 세우는 것이 목적이다.
스프링 내부 구현을 보기 전에 템플릿 메서드 패턴과 전략 패턴이 무엇인지에 대해 간단히 요약하고 들어가겠다.
템플릿 메서드 패턴은 상위 클래스가 전체 흐름(알고리즘 골격)을 정의하고, 하위 클래스는 그 중 변하는 부분만 구현하는 방식이다. 즉, 공통된 처리 순서를 유지하되 세부 동작만 달라지는 상황에서 중복을 줄이고, 일관성을 유지하기 위해 사용한다. 스프링에서는 AbstractXxx 형태의 이름으로 된 클래스 상당 수가 이 구조를 따른다.
아래는 템플릿 메서드 패턴의 구조를 가장 간단하게 보여주는 예시이다.
abstract class CoffeeMaker {
// 템플릿 메서드: 전체 흐름(변하지 않는 부분)
public final void make() {
boilWater();
brew();
pour();
}
private void boilWater() {
System.out.println("물 끓이는 중...");
}
private void pour() {
System.out.println("컵에 따르는 중...");
}
// 하위 클래스가 구현해야 하는 부분(변하는 부분)
protected abstract void brew();
}
class Americano extends CoffeeMaker {
@Override
protected void brew() {
System.out.println("아메리카노 추출...");
}
}
위 예시에서 볼 수 있듯 템플릿 메서드 패턴은 여러 구현체에서 흐름은 동일하지만 일부만 차이가 있을 시 사용하면 효과적이다.
이 패턴을 적용하면