Menu
Coddy logo textTech

템플릿 메서드 패턴

Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 87개 중 73번째.

템플릿 메서드 패턴(Template Method Pattern)은 알고리즘의 골격을 기본 클래스에서 정의하여, 하위 클래스가 전체 구조를 변경하지 않고도 특정 단계를 재정의할 수 있도록 하는 행동 디자인 패턴입니다. 이를 레시피와 같다고 생각하면 됩니다. 전체적인 요리 과정은 동일하게 유지되지만, 개별 재료나 기술은 달라질 수 있습니다.

이 패턴은 일련의 단계를 호출하는 템플릿 메서드가 포함된 추상 클래스를 사용합니다. 일부 단계는 기본 구현을 제공하지만, 다른 단계는 추상적이며 하위 클래스에서 반드시 구현해야 합니다:

abstract class DataProcessor {
    // 템플릿 메서드 - 알고리즘 구조를 정의합니다
    public final void process() {
        readData();
        processData();
        saveData();
    }
    
    abstract void readData();
    abstract void processData();
    
    // 기본 구현 (후크 메서드)
    void saveData() {
        System.out.println("Saving to default location");
    }
}

class CSVProcessor extends DataProcessor {
    void readData() {
        System.out.println("Reading CSV file");
    }
    
    void processData() {
        System.out.println("Parsing CSV data");
    }
}

class XMLProcessor extends DataProcessor {
    void readData() {
        System.out.println("Reading XML file");
    }
    
    void processData() {
        System.out.println("Parsing XML data");
    }
}

템플릿 메서드는 일반적으로 하위 클래스가 알고리즘의 구조를 변경하는 것을 방지하기 위해 final로 표시됩니다. 호출될 때, 모든 하위 클래스에 대해 동일한 순서를 실행합니다:

DataProcessor csv = new CSVProcessor();
csv.process();
// 출력:
// CSV 파일 읽는 중
// CSV 데이터 파싱 중
// 기본 위치에 저장 중

템플릿 메서드 패턴(Template Method Pattern)은 동일한 구조를 공유하지만 특정 단계에서 차이가 있는 알고리즘이 있을 때 이상적입니다. 이 패턴은 공통 로직을 기본 클래스에 배치하여 코드 재사용을 촉진하는 동시에 상속을 통한 커스터마이징을 허용합니다.

challenge icon

챌린지

쉬움

템플릿 메서드 패턴(Template Method Pattern)을 사용하여 문서 생성 시스템을 구축해 봅시다! 서로 다른 문서 유형(보고서 및 송장)이 동일한 생성 프로세스를 따르지만 특정 단계는 맞춤화하는 프레임워크를 만들 것입니다. 이는 전체적인 워크플로우는 고정되어 있지만 세부 사항이 문서 유형에 따라 달라지는 시나리오에 적합합니다.

코드는 네 개의 파일로 구성됩니다:

  • DocumentGenerator.java: 템플릿 메서드를 정의하는 추상 기본 클래스를 만듭니다. DocumentGenerator는 다음을 포함해야 합니다:

    createHeader(), createBody(), createFooter()의 세 단계를 순서대로 호출하여 알고리즘의 골격을 정의하는 final 메서드 generateDocument().

    하위 클래스에서 반드시 구현해야 하는 두 개의 추상 메서드: createHeader()createBody().

    --- End of Document ---를 출력하는 기본 구현을 가진 훅(hook) 메서드 createFooter().

  • ReportGenerator.java: 보고서 생성을 위한 구체적인 하위 클래스를 만듭니다. 생성자를 통해 보고서 제목(String)을 전달받아야 합니다.

    createHeader() 메서드는 === REPORT: [title] ===를 출력합니다.

    createBody() 메서드는 Report content goes here...를 출력합니다.

    상속받은 기본 푸터를 사용합니다.

  • InvoiceGenerator.java: 송장 생성을 위한 또 다른 구체적인 하위 클래스를 만듭니다. 생성자를 통해 고객 이름(String)과 금액(double)을 전달받아야 합니다.

    createHeader() 메서드는 *** INVOICE ***를 출력합니다.

    createBody() 메서드는 첫 번째 줄에 Customer: [name]를 출력하고, 다음 줄에 Amount Due: $[amount]를 출력합니다 (금액은 소수점 둘째 자리까지 형식화합니다).

    createFooter()를 오버라이드하여 Thank you for your business!를 출력합니다.

  • Main.java: 템플릿 메서드 시스템을 하나로 합칩니다! 보고서 제목(String), 고객 이름(String), 송장 금액(double)의 세 가지 입력을 받습니다.

    제목을 사용하여 ReportGenerator를 생성하고 generateDocument()를 호출합니다. 구분을 위해 빈 줄을 하나 출력합니다. 그런 다음 고객 이름과 금액을 사용하여 InvoiceGenerator를 생성하고 generateDocument()를 호출합니다.

보고서 제목(String), 고객 이름(String), 송장 금액(double) 순서대로 세 가지 입력을 받게 됩니다.

예를 들어, 입력값이 Q4 Sales, Acme Corp, 1500.00인 경우 출력은 다음과 같습니다:

=== REPORT: Q4 Sales ===
Report content goes here...
--- End of Document ---

*** INVOICE ***
Customer: Acme Corp
Amount Due: $1500.00
Thank you for your business!

두 문서 유형 모두 템플릿 메서드에 정의된 동일한 3단계 프로세스를 따르지만, 각 단계가 서로 다르게 맞춤화된 것을 확인해 보세요. ReportGenerator는 기본 푸터를 사용하는 반면 InvoiceGenerator는 자체 푸터를 제공합니다. 이것이 바로 템플릿 메서드 패턴에서 훅 메서드가 가진 힘입니다!

치트 시트

템플릿 메서드 패턴(Template Method Pattern)은 알고리즘의 구조를 기본 클래스에서 정의하고, 하위 클래스에서 전체 구조를 변경하지 않고 특정 단계를 재정의할 수 있도록 하는 행동 디자인 패턴입니다.

이 패턴은 일련의 단계를 호출하는 템플릿 메서드가 포함된 추상 클래스를 사용합니다. 일부 단계에는 기본 구현이 있으며, 다른 단계는 추상적이며 하위 클래스에서 반드시 구현해야 합니다:

abstract class DataProcessor {
    // 템플릿 메서드 - 알고리즘 구조를 정의합니다
    public final void process() {
        readData();
        processData();
        saveData();
    }
    
    abstract void readData();
    abstract void processData();
    
    // 기본 구현 (후크 메서드)
    void saveData() {
        System.out.println("Saving to default location");
    }
}

구체적인 하위 클래스는 추상 메서드를 구현합니다:

class CSVProcessor extends DataProcessor {
    void readData() {
        System.out.println("Reading CSV file");
    }
    
    void processData() {
        System.out.println("Parsing CSV data");
    }
}

템플릿 메서드는 하위 클래스가 알고리즘의 구조를 변경하지 못하도록 final로 표시됩니다. 호출되면 모든 하위 클래스에 대해 동일한 순서를 실행합니다:

DataProcessor csv = new CSVProcessor();
csv.process();
// 출력:
// Reading CSV file
// Parsing CSV data
// Saving to default location

주요 특징:

  • 템플릿 메서드는 final이며 알고리즘 구조를 정의합니다
  • 추상 메서드는 하위 클래스에서 반드시 구현해야 합니다
  • 후크 메서드는 선택적으로 재정의할 수 있는 기본 구현을 제공합니다
  • 공통 로직을 기본 클래스에 배치하여 코드 재사용을 촉진합니다

직접 해보기

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 입력 읽기
        String reportTitle = scanner.nextLine();
        String customerName = scanner.nextLine();
        double invoiceAmount = scanner.nextDouble();
        
        // TODO: title을 사용하여 ReportGenerator를 생성하고 generateDocument()를 호출하세요
        
        // TODO: 구분을 위해 빈 줄을 출력하세요
        
        // TODO: customer name과 amount를 사용하여 InvoiceGenerator를 생성하고 generateDocument()를 호출하세요
        
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨