728x90
Test 작성
@Slf4j
public class TemplateMethodTest {
@Test
public void templateMethod(){
logic1();
logic2();
}
private void logic1(){
long startTime = System.currentTimeMillis();
//비지니스 로직 실행
log.info("비지니스 로직1 실행");
//비지니스 로직 종료
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("resultTime = {}", resultTime);
}
private void logic2(){
long startTime = System.currentTimeMillis();
//비지니스 로직 실행
log.info("비지니스 로직2 실행");
//비지니스 로직 종료
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("resultTime = {}", resultTime);
}
}
logic1의 비즈니스 로직과, logic2의 비즈니스 로직을 제외하게 된다면 두 코드는 완벽하게 동일한 코드이다.
템플릿 메소드 패턴 작성하기

변하지 않는 코드(execute) , 변하는 코드(call)를 부모 자식 관계로 풀기
@Slf4j
public abstract class AbstractTemplate {
public void execute(){
long startTime = System.currentTimeMillis();
//비지니스 로직 실행
call();
//비지니스 로직 종료
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("resultTime = {}", resultTime);
}
protected abstract void call();
}
- 템플릿 메서드 패턴은 이름 그대로 템플릿을 사용하는 방식이다
- 템플릿은 기준이 되는 거대한 틀이다.
- 템플릿이라는 틀에 변하지 않는 부분을 몰아둔다.
- 그리고 일부 변하는 부분을 별도로 호출해서 해결한다.
- 변하지 않는 부분인 시간측정 로직을 하나의 메서드에 몰아두었다(하나의 템플릿)
- 템플릿 안에서 변하는 부분은 call() 메서드를 호출해서 처리한다.
- 템플릿 메서드 패턴은 부모 클래스에 변하지 않는 템플릿 코드를 둔다. 그리고 변하는 부분은 자식 클래스에 두고 상속과 오버 라이딩을 사용해서 처리한다
- JSP를 생각해 보면 큰 HTML에서 JAVA Code 부분만 변경해서 출력해 준다(템플릿)
Test

/**
* 템플릿 메소드 패턴 적용
*/
@Test
public void templateMethodV1(){
AbstractTemplate template1 = new SubClassLogic1();
template1.execute();
AbstractTemplate template2 = new SubClassLogic2();
template2.execute();
}
- template1.execute() 를 호출하면 템플릿 로직인 AbstractTemplate.execute()를 실행한다. 여기서 중간에 call() 메서드를 호출하는데, 이 부분이 오버라이딩 되어있다. 따라서 현재 인스턴스인 SubClassLogic1 인스턴스의 SubClassLogic1.call() 메서드가 호출된다
- 템플릿 메서드 패턴은 이렇게 다형성을 사용해서 변하는 부분과 변하지 않는 부분을 분리하는 방법이다.
익명 내부 클래스 사용하기
템플릿 메서드 패턴은 SubClassLogic1 , SubClassLogic2 처럼 클래스를 계속 만들어야 하는 단점이 있다. 익명 내부 클래스를 사용하면 이런 단점을 보완할 수 있다.
익명 내부 클래스를 사용하면 객체 인스턴스를 생성하면서 동시에 생성할 클래스를 상속 받은 자식 클래스를 정의할 수 있다. 이 클래스는 SubClassLogic1처럼 직접 지정하는 이름이 없고 클래스 내부에 선언되는 클래스여서 익명 내부 클래스라 한다
/**
* 익명 내부 클래스 사용한 템플릿 메소드 패턴
*/
@Test
public void templateMethodV2(){
AbstractTemplate template1 = new AbstractTemplate() {
@Override
protected void call() {
log.info("비지니스 로직1 실행");
}
};
log.info("클레스 이름1={}", template1.getClass());
template1.execute();
AbstractTemplate template2 = new AbstractTemplate() {
@Override
protected void call() {
log.info("비지니스 로직2 실행");
}
};
log.info("클레스 이름2={}", template2.getClass());
template2.execute();
}
- 실행 결과를 보면 자바가 임의로 만들어주는 익명 내부 클래스 이름은 TemplateMethodTest$1 , TemplateMethodTest$2 인 것을 확인할 수 있다.

728x90
'스프링 핵심 원리(고급편)' 카테고리의 다른 글
| Ch03. 템플릿 메서드 패턴과 콜백 패턴 - 전략 패턴 (0) | 2022.04.10 |
|---|---|
| Ch03. 템플릿 메서드 패턴과 콜백 패턴 - 템플릿 메서드 패턴(적용) (0) | 2022.04.09 |
| Ch03. 템플릿 메서드 패턴과 콜백 패턴 - 템플릿 메서드 패턴(시작) (0) | 2022.04.09 |
| Ch02. 쓰레드 로컬(ThreadLocal) - 쓰레드 로컬 동기화 (0) | 2022.04.08 |
| Ch02. 쓰레드 로컬(ThreadLocal) - ThreadLocal (0) | 2022.04.08 |