템플릿 메서드 패턴(Template Method Pattern) 은 소프트웨어 공학에서 동작 상의 알고리즘의 프로그램 뼈대를 정의하는 행위 디자인 패턴이다. 알고리즘의 구조를 변경하지 않고 알고리즘의 특정 단계들을 다시 정의할 수 있게 해준다.
상위 클래스 쪽에 템플릿에 해당하는 메서드가 정의되어 있고, 그 메서드의 정의 안에는 추상 메서드가 사용되고 있다.
추상 메서드를 실제로 구현하는 것은 하위 클래스이며, 하위 클래스에서 메서드를 구현하면 구체적인 처리가 결정된다.
그러나 어떤 하위 클래스에서 어떤 구현을 하더라도 처리의 큰 흐름은 상위 클래스에서 결정한대로 이루어지게 된다.
이와 같이 상위 클래스에서 처리의 뼈대를 결정하고, 하위 클래스에서 그 구체적인 내용을 결정하는 디자인 패턴을 템플릿 메서드 패턴(Template Method Pattern)이라고 한다.
https://upload.wikimedia.org/wikipedia/commons/2/2a/Template_Method_UML_class_diagram.svg
# Template method pattern
- 상속을 통해 기능을 확장하는 패턴
- 구체적인 것은 하위클래스에서 처리하도록 하는 구조
- 상속을 통해 슈퍼클래스의 기능을 확장할 때 사용하는 대표적인 방법
- 어떤 알고리즘에 대한 큰 틀이 결정된 상태에서 구체적인 설계를 서브클래스에 맡기는 디자인 패턴
- 상위클래스(템플릿)에 기본적인 로직의 흐름 구성, 그 일부를 추상 메서드·protected 메서드로 기술하여, 서브클래스에서 구현·오버라이딩 하도록 하는 패턴
- 스프링 프레임워크 등 프레임워크에서 주로 사용되는 구조
일주일에 1~2번은 꼭 먹게되는 음식. 외로운 자취생들뿐만 아니라 대한민국 국민 모두에게 라면은 정답입니다.
라면이라는 Abstract Class(추상 클래스) 와 핫!하고 착한 기업! 갓뚜기의 진짬뽕, 진짜장으로 Concrete Class(구체 클래스)로 템플릿 메서드 패턴(Template Method Pattern)을 공부해보자.
1. Common Abstract Class(공통 추상 클래스)
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
|
package com.acma.pattern.lamen;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public abstract class 라면 {
// Template Method
public void 라면을끓이자() {
라면을준비한다();
물이필요해();
면을넣는다();
물을버린다();
log.info("스프를 넣는다.");
먹는다();
}
// final keyword 로 수정불가
final void 물이필요해() {
log.info("냄비에 물을 적당히 채운다.");
}
// Abstract Method
abstract void 라면을준비한다();
// Hook Method
void 물을버린다() {
}
// Hook Method
void 면을넣는다() {
log.info("물이 끓으면 면을 넣는다.");
}
// Hook Method
void 먹는다() {
log.info("꼬들꼬들 맛있는 라면~ 냠냠!! 하고 먹는다.");
}
}
Colored by Color Scripter
|
- 추상클래스 안에 추상메서드를 선언하고 일반메서드를 구현하였다.
- 16 Line : 일반메서드로 처리할 수 있으나 "라면을끓이자" 라는 Template Method 에는 method 만 사용해야 하는게 아니라는 것을 보여주기 위한...(변명임...그냥 의미없이 코딩하였다...⊙_⊙;;;)
- 21-23 Line : 라면(추상)클래스를 상속받는 클래스에서 수정할 수 없도록 Final Keyword를 사용하였다.
- 27 Line : 라면(추상)클래스를 상속받는 구체클래스에 강제로 오버라이딩 시켜서 재정의 해야하는 추상메서드이다.
- 31 Line : 일반메서드이며 구체클래스에서 재정의를 해도 되고 안해도 되는 메서드이다. 보통 Hook 메서드라고 부른다. Hook 메서드는 상황에 맞게 정의하거나 하지 않아도 된다.
- 36-38 Line : 31 Line 과 동일.
- 41-43 Line : 31 Line 과 동일.
2. Concrete Class(구체 클래스)
◈ 진짬뽕 구체 클래스(진짬뽕 Concrete Class)
1
2
3
4
5
6
7
8
9
10
11
12
|
package com.acma.pattern.lamen;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class 진짬뽕 extends 라면 {
@Override
void 라면을준비한다() {
log.info("갓뚜기 진짬뽕을 준비한다.");
}
}
Colored by Color Scripter
|
- 6 Line : 진짬뽕 클래스는 라면(추상) 클래스를 상속받고 있다.
- 8-11 Line : 상속받은 라면(추상) 클래스에서 선언한 "라면을준비한다" 추상 메서드를 재정의하였다.
- 상속받은 라면(추상) 클래스의 Hook Method 를 재정의하지 않아도 문제가 없음을 알 수 있다.
◈ 진짜장 구체 클래스(진짜장 Concrete Class)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package com.acma.pattern.lamen;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class 진짜장 extends 라면 {
@Override
void 라면을준비한다() {
log.info("갓뚜기 진짜장을 준비한다.");
}
// Hook Method of 라면
void 물을버린다() {
log.info("액체스프를 비빌수 있는 양의 물만 남기고 물을 버린다.");
}
}
Colored by Color Scripter
|
- 6 Line : 진짜장 클래스는 라면(추상) 클래스를 상속받고 있다.
- 8-11 Line : 상속받은 라면(추상) 클래스에서 선언한 "라면을준비한다" 추상 메서드를 재정의하였다.
- 15-17 Line : 라면(추상) 클래스에 구현된 "물을버린다" 메서드를 진짜장(구체) 클래스에서 재정의 하였다.
※ 진짬뽕과 진짜장 구체 클래스를 보면 알 수 있듯이 "abstract" 키워드를 붙이면 추상 클래스를 상속받은 구체 클래스는 반드시 해당 메서드를 구현해야 하지만 "abstract" 키워드를 붙이지 않고 Hook 메서드로 만들면 반드시 구현할 필요가 없다는 것을 알 수 있다. 즉 Hook 메서드는 상속 받은 클래스에서 선택적으로 오버라이드할 수 있다는 것을 알 수 있다.
3. 실행
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package com.acma.pattern;
import org.junit.Test;
import com.acma.pattern.lamen.진짜장;
import com.acma.pattern.lamen.진짬뽕;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class 템플릿메서드패턴테스트 {
@Test
public void 테스트() {
log.info("============================== [ 진짬뽕 ]");
진짬뽕 짬뽕라면 = new 진짬뽕();
짬뽕라면.라면을끓이자();
log.info("============================== [ 진짜장 ]");
진짜장 짜장라면 = new 진짜장();
짜장라면.라면을끓이자();
}
}
Colored by Color Scripter
|
- 13 Line : main 패키지의 main 메서드에서 실행할 수도 있지만 필자는 test 패키지에서 Junit Test 를 통해 코드를 실행하는 것을 선호한다.
4. 결과
- 진짬뽕의 경우 라면(추상) 클래스의 추상 메서드만 재정의하였다.
- 진짜장의 경우 라면(추상) 클래스의 추상 메서드와 Hook 메서드를 재정의하였다.
# 라면의 레시피는 본인의 취향에 따라 달라질 수 있다. 소스 코드의 경우도 개발자 본인의 취향에 따라 달라질 수 있다. 하지만 라면마다 추천하는 다양한 레시피가 있듯이 '소스 코드를 작성하는 다양한 방법에 대해서 알고 있다면 더 좋은 소스 코드가 나오지 않을까' 라는 생각을 하게된다.
'Design Pattern' 카테고리의 다른 글
[Design Pattern] 전략 패턴(Strategy Pattern) - (2) (0) | 2019.07.30 |
---|---|
[Design Pattern] 객체 지향 설계 5원칙 - SOLID (0) | 2019.07.25 |
[Design Pattern] 전략 패턴(Strategy Pattern) - (1) (0) | 2019.07.25 |