728x90
✏️ 개요
템플릿 메서드 패턴은 부모 클래스에 변하지 않는 템플릿 코드를 둔다. 그리고 변하는 부분은 자식 클래스에 두고 상속과 오버라이딩을 사용해서 처리한다.
💻 자바에 적용
- 템플릿
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();
}
- 자식 클래스
public class SubClassLogic1 extends AbstractTemplate{
@Override
protected void call() {
log.info("비즈니스 로직1 실행");
}
}
- 템플릿 메서드 패턴 적용
@Test
void templateMethodV1() {
AbstractTemplate template1 = new SubClassLogic1();
template1.execute();
AbstractTemplate template2 = new SubClassLogic2();
template2.execute();
}
- 결과
00:33:25.838 [Test worker] INFO hello.advanced.trace.template.code.SubClassLogic1 -- 비즈니스 로직1 실행
00:33:25.840 [Test worker] INFO hello.advanced.trace.template.code.AbstractTemplate -- resultTime = 3
00:33:25.841 [Test worker] INFO hello.advanced.trace.template.code.SubClassLogic2 -- 비즈니스 로직2 실행
00:33:25.841 [Test worker] INFO hello.advanced.trace.template.code.AbstractTemplate -- resultTime = 0
- 템플릿 메서드 패턴 인스턴스 호출 그림
- template.execute()를 호출하면 템플릿 로직인 AbstractTemplate.execute()를 실행한다.
- 중간에 call() 메서드를 호출하는데, 이 부분이 오버라이딩 되어있다.
- 따라서 현재 인스턴스인 SubClassLogic1 인스턴스의 SubClassLogic1.call() 메서드가 호출된다.
📌 익명 내부 클래스 사용
/**
* 익명 내부 클래스 사용
*/
@Test
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();
}
- 결과
00:45:57.962 [Test worker] INFO hello.advanced.trace.template.TemplateMethodTest -- 클래스 이름1 = class hello.advanced.trace.template.TemplateMethodTest$1
00:45:57.964 [Test worker] INFO hello.advanced.trace.template.TemplateMethodTest -- 비즈니스 로직1 실행
00:45:57.964 [Test worker] INFO hello.advanced.trace.template.code.AbstractTemplate -- resultTime = 0
00:45:57.965 [Test worker] INFO hello.advanced.trace.template.TemplateMethodTest -- 클래스 이름2 = class hello.advanced.trace.template.TemplateMethodTest$2
00:45:57.965 [Test worker] INFO hello.advanced.trace.template.TemplateMethodTest -- 비즈니스 로직2 실행
00:45:57.965 [Test worker] INFO hello.advanced.trace.template.code.AbstractTemplate -- resultTime = 0
👉🏻 정리
템플릿 메서드 패턴은 상속과 오버라이딩을 통한 다형성을 사용해서 변하는 부분과 변하지 않는 부분을 분리하는 방법이다.
🔨 문제점
템플릿 메서드 패턴은 상속을 사용한다. 따라서 상속에서 오는 단점들을 그대로 안고간다. 특히 자식 클래스가 부모 클래스와 컴파일 시점에 강하게 결합되는 문제가 있는데, 이 것이 의존관계에 대한 문제이다.
자식 클래스 클래스 입장에서는 부모 클래스의 기능을 전혀 사용하지 않는데도 불구하고 템플릿 메서드 패턴을 위해 부모 클래스를 상속받고 있다. 그리고 UML에서 상속을 받으면 삼각형 화살표가 자식 -> 부모를 향하고 있는데 이것이 의존관계를 반영하는 것이다.
추가로 템플릿 메서드 패턴은 상속 구조를 사용하기 때문에 별도의 클래스나 익명 내부 클래스를 만들어야 하는 부분도 복잡하다.
728x90
'디자인 패턴 > GOF' 카테고리의 다른 글
Proxy Pattern, Decorator Pattern (0) | 2023.09.22 |
---|---|
Template Method Pattern 적용 (0) | 2023.09.22 |
Strategy Pattern (0) | 2023.06.10 |