Menu
Coddy logo textTech

템플릿 메서드 패턴

Coddy C# 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 70개 중 59번째.

Template Method 패턴은 base class에서 algorithm의 뼈대를 정의하고, 전체 구조를 변경하지 않고도 하위 class가 특정 단계를 재정의할 수 있도록 하는 행동 패턴입니다. base class가 작업 흐름을 제어하고, 파생 class가 개별 구성 요소를 사용자 지정합니다.

이 패턴은 상속과 abstract 메서드를 사용합니다. base 클래스에는 일련의 단계를 호출하는 "템플릿 method"가 포함되어 있으며, 그중 일부는 abstract이고 하위 클래스에서 구현해야 합니다.

public abstract class DataProcessor
{
    // 템플릿 메서드 - 알고리즘 구조를 정의합니다
    public void Process()
    {
        ReadData();
        ProcessData();
        SaveData();
    }
    
    protected abstract void ReadData();
    protected abstract void ProcessData();
    protected virtual void SaveData() => Console.WriteLine("Saving to default location");
}

public class CsvProcessor : DataProcessor
{
    protected override void ReadData() => Console.WriteLine("Reading CSV file");
    protected override void ProcessData() => Console.WriteLine("Parsing CSV data");
}

public class JsonProcessor : DataProcessor
{
    protected override void ReadData() => Console.WriteLine("Reading JSON file");
    protected override void ProcessData() => Console.WriteLine("Parsing JSON data");
    protected override void SaveData() => Console.WriteLine("Saving to cloud");
}

각 하위 클래스는 자체 implementation을 제공하는 반면, base class는 작업의 order를 강제합니다:

DataProcessor csv = new CsvProcessor();
csv.Process();
// CSV 파일 읽기
// CSV 데이터 파싱
// Saving to default location

DataProcessor json = new JsonProcessor();
json.Process();
// JSON 파일 읽기
// JSON 데이터 파싱
// 클라우드에 저장

Template Method 패턴은 여러 class가 동일한 algorithm 구조를 공유하지만 구체적인 단계에서는 서로 다를 때 적합합니다. 공통 로직을 base class에 배치하는 동시에 재정의 가능한 method를 통해 유연성을 제공함으로써 코드 재사용을 촉진합니다.

challenge icon

챌린지

쉬움

Template Method 패턴을 사용하여 report 생성 시스템을 구축해 봅시다. 서로 다른 유형의 report(예: 판매 report와 inventory report)는 동일한 전체 구조를 공유합니다. 즉, 모두 data를 수집하고, 형식을 지정하고, 결과를 출력해야 하지만 각 report 유형은 이러한 단계를 서로 다르게 처리합니다.

코드를 세 개의 파일로 구성합니다:

  • ReportGenerator.cs: Reporting namespace에 abstract ReportGenerator class를 Create합니다. 이 base class는 Generate()라는 template method를 통해 report 생성 algorithm의 뼈대를 정의합니다. 이 method는 세 단계를 순서대로 호출해야 합니다: GatherData(), FormatReport(), OutputReport(). GatherData()FormatReport()는 abstract로 만들고(각 report 유형이 이를 서로 다르게 implementation합니다), OutputReport()Sending to default printer를 print하는 default implementation이 있는 virtual method로 만들어야 합니다.
  • ConcreteReports.cs: 동일한 namespace에 ReportGenerator를 상속하는 두 개의 구체적인 report class를 Create합니다:
    • SalesReport - GatherData()를 구현하여 Collecting sales data from database를 print하고, FormatReport()를 구현하여 Formatting as sales summary를 print합니다.
    • InventoryReport - GatherData()를 구현하여 Scanning warehouse inventory를 print하고, FormatReport()를 구현하여 Formatting as inventory list를 print하며, OutputReport()를 override하여 Sending to warehouse manager를 print합니다.
  • Program.cs: report 인스턴스를 Create하고 이를 생성하여 모든 것을 하나로 결합합니다. template method는 각 report가 동일한 3단계 Process를 따르도록 보장하지만, 각 단계의 구체적인 동작은 report 유형에 따라 달라집니다.

하나의 입력을 받습니다:

  • report 유형: sales 또는 inventory

입력에 따라 appropriate report generator를 Create하고 해당 generator의 Generate() method를 호출합니다.

예를 들어 입력이 sales이면 출력은 다음과 같아야 합니다:

Collecting sales data from database
Formatting as sales summary
Sending to default printer

입력이 inventory이면 출력은 다음과 같아야 합니다:

Scanning warehouse inventory
Formatting as inventory list
Sending to warehouse manager

두 report가 정확히 동일한 algorithm 구조(수집, 형식 지정, 출력)를 따르지만 각 단계의 implementation은 사용자 지정된다는 점에 주목하세요. SalesReport는 default 출력 동작을 사용하는 반면, InventoryReport는 이를 override합니다. 이는 Template Method 패턴을 통해 어떤 단계는 반드시 override해야 하고 어떤 단계는 선택적으로 사용자 지정할 수 있는지 제어하는 방법을 보여 줍니다!

직접 해보기

using System;
using Reporting;

class Program
{
    public static void Main(string[] args)
    {
        string reportType = Console.ReadLine();
        
        // TODO: reportType에 따라 적절한 보고서 생성기를 만드세요
        // reportType이 "sales"이면 SalesReport를 만드세요
        // reportType이 "inventory"이면 InventoryReport를 만드세요
        // 그런 다음 보고서에 대해 Generate() 메서드를 호출하세요
        
    }
}
quiz icon실력 점검

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

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

직접 연습해 보세요: 온라인 C# 컴파일러