참치코더의 꿈 메모장

디자인 패턴 / 템플릿 메서드 패턴 본문

디자인 패턴

디자인 패턴 / 템플릿 메서드 패턴

참치깡 2025. 10. 14. 14:21
728x90

 

템플릿 메서드 패턴은 알고리즘의 기본 골격은 상위 클래스(추상 클래스)에 정의하고, 세부적인 구현은

하위 클래스에서 담당하도록 하는 패턴이다.

 

공통된  처리 절차는 유지하면서, 일부 단계의 구체적인 구현만 서브클래스가 오버라이드해서 바꿀 수 있게 하는 구조이다.

 

핵심 개념

 

상위 클래스(추상 클래스)

 

- 알고리즘의 공통 흐름(템플릿)을 정의

- 특정 단계(훅 메서드)는 추상 메서드로 두어 하위 클래스가 구체화

 

하위 클래스

 

- 추상 메서드를 구현하여 세부 동작을 정의

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// 추상 클래스 (템플릿 정의)
 
abstract class BeverageTemplate {
    
    // 템플릿 메서드 (변하지 않는 전체 알고리즘의 흐름)
    public final void prepareBeberage() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }
 
    private void boilWater(){
        System.out.println("물을 끓이는 중...");
    }
 
    private void pourIncup(){
        System.out.println("컵에 따르는 중...");
    }
 
    // 하위 클래스에서 구체적으로 구현할 부분
    protected abstract void brew();
    protected abstract void addCondiments();
}
 
// 하위 클래스 1 (커피)
 
class Coffee extends BeverageTemplate {
    
    @Override
    protected void brew() {
        System.out.println("커피를 내리는 중...");
    }
 
    @Override
    protected void addCondiments() {
        protected void addCondiments() {
            System.out.println("설탕과 우유를 추가합니다.")
        }
    }
 
// 하위 클래스 2 (티)
 
class Tea extends BeverageTemplate {
    
    @Override
    protected void brew() {
        System.out.println("차 티백을 우리는 중...");
    }
 
    @Override
    protected void addCondiments() {
        System.out.println("레몬을 추가합니다.");        
    }
}
 
 
// 실행
 
public class TemplateMethodExample {
    public static void main(String[] args) {
        
        BeverageTemplate coffee = new Coffee();
        coffee.prepareBeverage();
 
        System.out.println();
 
        BeverageTemplate tea = new Tea();
        tea.prepareBeverage();
 
        
    }
}
 
 
 
 
cs

 

스프링 프레임워크랑 스프링 부트 내에서는 어떨까?

 

- 스프링에서는 템플릿 메서드 패턴이 널리 사용된다.

- (그냥 전체적인 메커니즘이 템플릿 메서드 패턴으로 구현되어있다고 해도 과장이 아니다)

 

- 공통 흐름은 프레임워크가 담당하고, 개발자는 필요한 부분만 정의하는 구조가 스프링 철학과

  딱 맞다...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public abstract class ApiTemplate {
    
    // 템플릿 메서드
    public final void execute() {
        try {
            beforeRequest();
            callApi();
            afterRequest();
        } catch (Exception e) {
            handleError(e);
        }
    }
 
    protected void beforeRequest() {
        System.out.println("요청 시작 로깅...");
    }
 
    protected abstract void callApi();
 
    protected void afterRequest(){
        System.out.println("요청 완료 로깅...");
    }
 
    protected void handleError(Exception e){
        System.out.println("에러 발생: " + e.getMessage());
    }
 
}
 
// 구체 서비스에서 해당 메서드 구현
 
@Service
public class KakaoApiService extends ApiTemplate {
    
    @Override
    protected void callApi() {
        System.out.println("카카오 API 호출 실행");
    }
}
 
@Service
public class NaverApiService extemds ApiTemplate {
 
    @Override
    protected void callApi() {
        System.out.println("네이버 API 호출 실행");
    }
}
 
// 공통 로깅과 예외 처리는 유지하면서 API별 구현만 다르게 동작함
 
 
 
 
 
 
cs

 

728x90
Comments