템플릿 메서드 패턴
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)은 동일한 구조를 공유하지만 특정 단계에서 차이가 있는 알고리즘이 있을 때 이상적입니다. 이 패턴은 공통 로직을 기본 클래스에 배치하여 코드 재사용을 촉진하는 동시에 상속을 통한 커스터마이징을 허용합니다.
챌린지
쉬움템플릿 메서드 패턴(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()를 호출하세요
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
4상속
상속의 기초 (extends)super 키워드메서드 오버라이딩 (@Override)생성자 체이닝Object 클래스단일 및 다중 레벨 상속다중 클래스 상속이 불가능한 이유요약 - 직원 계층 구조