본문 바로가기
객체지향/디자인패턴

템플릿 메서드 패턴

by 정재익 2026. 2. 15.

GOF 디자인패턴의 하나이다. 행위 패턴으로 구분되어있다.

템플릿 메서드 패턴은 부모 클래스에 알고리즘의 골격인 템플릿을 정의하고, 일부 변경되는 로직은 자식 클래스에 정의한다. 이렇게 하면 자식 클래스가 알고리즘의 전체 구조를 변경하지 않고 특정 부분만 재정의할 수 있다. 상속과 오버라이딩을 통한 다형성으로 문제를 해결하는 것이다.

 

 

단점 : 상속을 사용하여 상속의 단점을 안고간다. 자식 클래스가 부모 클래스가 컴파일 시점에 강결합된다. 자식 클래스는 부모 클래스의 로직을 전혀쓰지 않는다. 그럼에도 자식 클래스는 부모 클래스를 상속하고 있다. 상속을 받는다는 것은 의존하고 있다는 것이다. 부모클래스의 영향이 자식에게도 전달된다는 것 예를들어 부모클래스에서 추상 메서드가 하나 더 생기면 자식 클래스들은 다 구현해줘야한다. 템플릿 메서드와 비슷한 역할을 하면서 상속의 단점을 제거할 수 있는 패턴은 전략패턴이다.

 

@Slf4j
public class TemplateMethodTest {
    @Test
    void templateMethodV0() {
        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);
    }
}

비즈니스 로직과 시간측정이라는 것이 합쳐있다.

 

템플릿메서드는 추상클래스를 이용한다.

@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() 메서드를 호출해서 처리 템플릿메서드 패턴은 부모 클래스에 변하지 않는 템플릿 코드를 둔다. 그리고 변하는 부분은 자식 클래스에 두고 상속과 오버라이딩을 사용해서 처리한다.

 

@Slf4j
public class SubClassLogic1 extends AbstractTemplate{
    @Override
    protected void call() {
        log.info("비즈니스 로직1 실행");
    }
}
@Slf4j
public class SubClassLogic2 extends AbstractTemplate{
    @Override
    protected void call() {
        log.info("비즈니스 로직2 실행");
    }
}

 

 

@Test
void templateMethodV1() {
    AbstractTemplate template1 = new SubClassLogic1();
    template1.execute();
    AbstractTemplate template2 = new SubClassLogic1();
    template2.execute();
}

익스큐트를 실행하면 추상클래스를 실행 그리고 변하는 부분만 자식클래스로 간다.

 

혹시나 템플릿에 변경이 일어나면 예를들어 결과시간을 다른 시간으로 바꿀 때 이전이었으면 2개를 바꿔야하지만 지금은 하나만 바꿔도된다.

 

그러나 지금과 같은 방식은 서브클래스를 계속 만들어야한다. 이럴 때는 익명 내부 클래스를 사용한다.

익명 내부 클래스는 객체 인스턴스를 생성하면서 동시에 생성할 클래스를 상속 받은 자식 클래스를 정의할 수 있다.

 

익명 내부 클래스를 사용하는 방식

@Test
void templateMethodV2() {
    AbstractTemplate template1 = new AbstractTemplate() {

        @Override
        protected void call() {
            log.info("비즈니스 로직1 실행");
        }
    };
    template1.execute();

    AbstractTemplate template2 = new AbstractTemplate() {

        @Override
        protected void call() {
            log.info("비즈니스 로직2 실행");
        }
    };
    template2.execute();
}

 

다른 예제

이것은 익명내부클래스를 활용하지 않은 예제다.

public abstract class DataProcessor {

    // 템플릿 메서드
    public final void process() {
        loadData();
        processData();
        saveData();
    }

    protected void loadData() {
        System.out.println("데이터 로딩");
    }

    // 변하는 부분
    protected abstract void processData();

    protected void saveData() {
        System.out.println("데이터 저장");
    }
}
public class CsvDataProcessor extends DataProcessor {
    @Override
    protected void processData() {
        System.out.println("CSV 데이터 처리");
    }
}

public class JsonDataProcessor extends DataProcessor {
    @Override
    protected void processData() {
        System.out.println("JSON 데이터 처리");
    }
}
DataProcessor processor = new CsvDataProcessor();
processor.process();

 

 

템플릿 메소드패턴의 한 형태로서 팩토리 메서드 패턴도 있다. 그것은 객체 생성 책임을 서브클래스에 위임하고 생성로직과 사용로직을 분리하는 생성 패턴이다. if else를 남발하지 않고 하나의 추상메서드를 활용 그리고 그 추상 메서드는 어떤 객체를 생성할지만 정의하고 각 서브 클래스가 생성 책임을 지닌다 그럼 다른 종류의 구현체라도 if else없이 한번의 코드로 구현이 가능하다

 

'객체지향 > 디자인패턴' 카테고리의 다른 글

템플릿 콜백 패턴  (0) 2026.02.18
전략 패턴  (0) 2026.02.18
옵저버 패턴  (0) 2026.02.12
프록시 패턴  (0) 2026.01.04
싱글톤 패턴  (0) 2025.12.21