알고리즘의 뼈대를 정의하고, 일부 단계를 서브클래스에 연기하는 방법이다.
재사용성과 확장성을 중시하는 상황에서 유용하다.
템플릿 메서드
알고리즘의 골격(어떤 작업을 수행하는 데 필요한 여러 단계의 순서)을 제공한다.
메서드는 자체적으로 변경되지 않으며, 서브클래스에서 오버라이드할 수 있는 하나 이상의 추상메서드를 호출한다.
추상 메서드
서브클래스에서 구현해야 하는 메서드이다.
템플릿 메서드는 이러한 메서드들을 호출해 전체 알고리즘의 일부를 구성한다.
후크 메서드
선택적으로 오버라이드할 수 있는 메서드이다.
서브클래스에서 필요에 따라 구현할 수 있으며, 알고리즘의 특정 포인트에서 추가적인 작업을 수행할 수 있게 한다.
장점
- 코드 재사용성: 공통된 알고리즘의 코드를 상위 클래스에 한 번만 작성해 여러 하위 클래스에서 재사용할 수 있다.
- 확장성: 새로운 클래스를 만들고 템플릿 메서드의 특정 단계를 다르게 구현함으로써 기존 코드를 변경하지 않고 알고리즘의 행동을 확장할 수 있다.
- 제어의 역전: 프로그램의 흐름을 상위 클래스가 제어하며, 하위 클래스는 특정 작업을 구현함으로써 이를 따른다.
예시
추상 클래스
public abstract class DataProcessor {
// 템플릿 메서드
public final void process() {
openResource();
readData();
beforeProcessing(); // 후크 메서드 호출
processData();
afterProcessing(); // 후크 메서드 호출
writeData();
closeResource();
}
private void openResource() {
System.out.println("Resource opened.");
}
private void closeResource() {
System.out.println("Resource closed.");
}
// 서브클래스에서 구현될 추상 메서드
protected abstract void readData();
protected abstract void processData();
protected abstract void writeData();
// 후크 메서드
protected void beforeProcessing() {
// 기본적으로 아무 작업도 하지 않음
}
protected void afterProcessing() {
// 기본적으로 아무 작업도 하지 않음
}
}
서브 클래스
public class XmlDataProcessor extends DataProcessor {
@Override
protected void readData() {
System.out.println("Reading XML data.");
}
@Override
protected void processData() {
System.out.println("Processing XML data.");
}
@Override
protected void writeData() {
System.out.println("Writing processed XML data.");
}
}
public class JsonDataProcessor extends DataProcessor {
@Override
protected void readData() {
System.out.println("Reading JSON data.");
}
@Override
protected void processData() {
System.out.println("Processing JSON data.");
}
@Override
protected void writeData() {
System.out.println("Writing processed JSON data.");
}
}