템플릿 메서드 패턴
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를 통해 유연성을 제공함으로써 코드 재사용을 촉진합니다.
챌린지
쉬움Template Method 패턴을 사용하여 report 생성 시스템을 구축해 봅시다. 서로 다른 유형의 report(예: 판매 report와 inventory report)는 동일한 전체 구조를 공유합니다. 즉, 모두 data를 수집하고, 형식을 지정하고, 결과를 출력해야 하지만 각 report 유형은 이러한 단계를 서로 다르게 처리합니다.
코드를 세 개의 파일로 구성합니다:
ReportGenerator.cs:Reportingnamespace에 abstractReportGeneratorclass를 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() 메서드를 호출하세요
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C# 컴파일러