본문 바로가기
LV3_Advanced/GOF 패턴

Template Method (템플릿 메서드) - 행위 패턴 #1

by 하타라시 2026. 2. 19.

목차

💡
  • 왜 템플릿 메서드 패턴을 사용해야 하는가?
  • 설계도는 어떻게 생겼나?
  • 실제로 어떻게 구현하나?
  • 장점과 단점은 무엇인가?

왜 템플릿 메서드 패턴을 사용해야 하는가?

이 패턴의 가장 큰 특징은 알고리즘의 전체적인 실행 흐름을 상위 클래스에 정의하고, 구체적인 세부 단계는 하위 클래스에서 정의하는 것입니다.

예를 들어, 커피와 홍차를 만들 때, 물을 끓이고, 첨가물을 넣는 과정은 템플릿화 할 수 있습니다. 물을 끓이는 과정은 상위에 구현하고, 첨가물을 넣는 디테일한 과정은 하위에서 구현하는 개념입니다.

설계도는 어떻게 생겼나?

부모 클래스는 실행 순서를 정의하고, 자식 클래스는 그 순서 안에서 필요한 단계만 구현하도록 설계됩니다.

또한 공통으로 사용되는 로직은 부모 클래스에 함께 정의할 수 있습니다.

실패

실제로 어떻게 구현하나?

추상 클래스 설계

abstract class Beverage {
    // 자식이 흐름을 바꾸지 못하게 final로 선언하는 것이 관례입니다.
    public final void prepareRecipe() {
        boilWater();       // 1단계: 물 끓이기 (공통)
        brew();            // 2단계: 우려내기 (자식이 구현)
        pourInCup();       // 3단계: 컵에 따르기 (공통)
        addCondiments();   // 4단계: 첨가물 넣기 (자식이 구현)
    }

    // 자식 클래스에서 반드시 구체화해야 하는 메서드들
    protected abstract void brew();
    protected abstract void addCondiments();

    // 모든 자식이 동일하게 사용하는 공통 메서드
    private void boilWater() {
        System.out.println("물을 끓입니다.");
    }

    private void pourInCup() {
        System.out.println("컵에 따릅니다.");
    }
}

구현 단계 및 실행

class Coffee extends Beverage {
    @Override
    protected void brew() {
        System.out.println("필터로 원두를 추출합니다.");
    }

    @Override
    protected void addCondiments() {
        System.out.println("설탕과 우유를 넣습니다.");
    }
}

// 구현 클래스: 홍차 (추상 메서드를 구체화)
class Tea extends Beverage {
    @Override
    protected void brew() {
        System.out.println("찻잎을 뜨거운 물에 우려냅니다.");
    }

    @Override
    protected void addCondiments() {
        System.out.println("레몬을 띄웁니다.");
    }
}

// 실행부: 메인 클래스
public class Main {
    public static void main(String[] args) {
        System.out.println("--- 커피 만들기 ---");
        Beverage coffee = new Coffee();
        coffee.prepareRecipe(); 

        System.out.println("\\n--- 홍차 만들기 ---");
        Beverage tea = new Tea();
        tea.prepareRecipe();
    }
}

장점과 단점은 무엇인가?

장점

  • 코드 중복 제거
    • 하위 클래스들이 공통적으로 가지는 로직을 상위 클래스로 한 번만 작성하므로, 생산성이 올라갑니다.
  • 자식 클래스의 역할 축소
    • 핵심적인 알고리즘 흐름은 상위 클래스에서 관리하므로, 하위클래스는 자신에게 할당된 특정 단계만 구현하면 됩니다.

단점

  • 상속으로 인한 유연성 제한
    • 상속을 사용하므로, 부모 클래스와 자식 클래스가 강하게 결합이 됩니다.
    • 부모 클래스의 템플릿 구조가 변경되면, 이를 상속받는 모든 하위 클래스에 영향을 줄 수 있습니다. 따라서 상위 클래스 설계가 매우 중요합니다.
  • 의도치 않은 오버라이딩 가능
    • 템플릿 메서드 패턴은 부모가 정해준대로 동작하기를 요구합니다. 하지만 오버라이딩을 통해 다른 동작을 구현하거나 예외를 던질게 될 경우 패턴이 망가지게 됩니다.