템플릿 메서드 패턴은 알고리즘의 구조를 정의하고, 알고리즘의 일부 단계를 서브 클래스에서 구현할 수 있도록 한다. 알고리즘의 뼈대는 상위 클래스에서 제공하고 세부 구현은 하위 클래스에서 제공한다.
주요 개념 부터 알아보자.
1. Abstract Class (추상 클래스) : 알고리즘의 뼈대를 정의하는 템플릿 메서드를 포함한다. 알고리즘의 각 단계를 정의하며, 일부 단계는 추상 메서드로 선언하여 서브 클래스에서 구현하도록 한다.
2. Concrete Class (구체 클래스) : 추상 클래스에서 정의된 추상 메서드를 구현하여 알고리즘의 각 단계를 정의한다.
예시 소스코드를 살펴보자.
요리를 하는 과정을 템플릿 메서드 패턴으로 구현해본다. 요리는 재료준비, 요리, 설거지 이런 단계가 가장 큰 틀이다 각 세부 구현은 요리 종류에 따라 달라질 수 있다.
abstract class Cooking {
// 템플릿 메서드
public final void cook() {
prepareIngredients();
cookDish();
cleanUp();
}
// 알고리즘의 단계들
protected abstract void prepareIngredients();
protected abstract void cookDish();
// 공통 단계
protected void cleanUp() {
System.out.println("Cleaning up the kitchen...");
}
}
class ItalianCooking extends Cooking {
@Override
protected void prepareIngredients() {
System.out.println("Preparing ingredients for Italian dish...");
}
@Override
protected void cookDish() {
System.out.println("Cooking Italian dish...");
}
}
class JapaneseCooking extends Cooking {
@Override
protected void prepareIngredients() {
System.out.println("Preparing ingredients for Japanese dish...");
}
@Override
protected void cookDish() {
System.out.println("Cooking Japanese dish...");
}
}
public class TemplateMethodPatternDemo {
public static void main(String[] args) {
Cooking italianCooking = new ItalianCooking();
italianCooking.cook();
System.out.println();
Cooking japaneseCooking = new JapaneseCooking();
japaneseCooking.cook();
}
}
// 출력
//Preparing ingredients for Italian dish...
//Cooking Italian dish...
//Cleaning up the kitchen...
//Preparing ingredients for Japanese dish...
//Cooking Japanese dish...
//Cleaning up the kitchen...
설거지는 모두 동일하겠지만 이탈리안 요리를 준비하거나 일식을 준비하는 과정은 다르고 결과도 다를것이다.
서브클래스의 책임이 증가하지만 코드를 재사용할 수 있고 서브 클래스에서 구현하는 단계들을 통해 유연성을 가질 수 있다.
현업에서도 많이 사용하는 웹 애플리케이션 요청 처리에 대해서 소스코드로 살펴보며 패턴을 이해하보자.
요청을 처리하고 결과를 반환하기전에 인증, 권한 확인, 로깅 등의 작업을 수행해야 한다고 생각해보자.
abstract class HttpRequestHandler {
// 템플릿 메서드
public final void handleRequest() {
authenticate();
authorize();
handle();
logRequest();
}
protected abstract void authenticate();
protected abstract void authorize();
protected abstract void handle();
// 공통 단계
protected void logRequest() {
System.out.println("Logging request...");
}
}
class GetRequestHandler extends HttpRequestHandler {
@Override
protected void authenticate() {
System.out.println("Authenticating GET request...");
}
@Override
protected void authorize() {
System.out.println("Authorizing GET request...");
}
@Override
protected void handle() {
System.out.println("Handling GET request...");
}
}
class PostRequestHandler extends HttpRequestHandler {
@Override
protected void authenticate() {
System.out.println("Authenticating POST request...");
}
@Override
protected void authorize() {
System.out.println("Authorizing POST request...");
}
@Override
protected void handle() {
System.out.println("Handling POST request...");
}
}
public class TemplateMethodPatternHttpRequestDemo {
public static void main(String[] args) {
HttpRequestHandler getRequestHandler = new GetRequestHandler();
getRequestHandler.handleRequest();
System.out.println();
HttpRequestHandler postRequestHandler = new PostRequestHandler();
postRequestHandler.handleRequest();
}
}
// 출력
//Authenticating GET request...
//Authorizing GET request...
//Handling GET request...
//Logging request...
//Authenticating POST request...
//Authorizing POST request...
//Handling POST request...
//Logging request...
이런식으로 구현하면 공통된 처리 흐름을 유지하면서 각 단계의 구체적인 구현을 다양하게 할 수 있다.
'Design Pattern > 행동 패턴(Behavioral Patterns)' 카테고리의 다른 글
방문자(Visitor) - 행동 패턴(Behavioral Patterns) (0) | 2024.05.25 |
---|---|
전략(Strategy) - 행동 패턴(Behavioral Patterns) (0) | 2024.05.25 |
상태(State) - 행동 패턴(Behavioral Patterns) (0) | 2024.05.25 |
옵저버(Observer) - 행동 패턴(Behavioral Patterns) (0) | 2024.05.25 |
메멘토(Memento) - 행동 패턴(Behavioral Patterns) (0) | 2024.05.25 |