Menu
Coddy logo textTech

템플릿 메서드 패턴

Coddy Dart 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 110개 중 97번째.

Template Method 패턴은 base 클래스에서 algorithm의 뼈대를 정의하여, 하위 클래스가 전체 구조를 변경하지 않고 특정 단계를 재정의할 수 있도록 합니다. base 클래스는 workflow를 제어하고, 하위 클래스는 개별 단계를 사용자 지정합니다.

이 패턴은 상속을 사용합니다. abstract class는 일련의 단계를 호출하는 템플릿 메서드를 defines합니다. 이러한 단계 중 일부는 abstract 단계(하위 클래스에서 구현해야 함)이고, 일부는 기본 구현을 가집니다.

abstract class DataProcessor {
  // 템플릿 메서드 - 알고리즘 구조를 정의함
  void process() {
    readData();
    processData();
    saveData();
  }

  void readData();      // 추상 - 서브클래스가 반드시 구현해야 함
  void processData();   // 추상 - 서브클래스가 반드시 구현해야 함

  void saveData() {     // 기본 구현
    print('Data saved to database');
  }
}

class CsvProcessor extends DataProcessor {
  @override
  void readData() => print('Reading CSV file');

  @override
  void processData() => print('Parsing CSV rows');
}

class JsonProcessor extends DataProcessor {
  @override
  void readData() => print('Reading JSON file');

  @override
  void processData() => print('Parsing JSON objects');

  @override
  void saveData() => print('Saved to cloud storage');
}

void main() {
  var csv = CsvProcessor();
  csv.process();
  // CSV 파일 읽기
  // CSV 행 파싱
  // 데이터베이스에 데이터 저장됨

  var json = JsonProcessor();
  json.process();
  // JSON 파일 읽기
  // JSON 객체 파싱
  // 클라우드 스토리지에 저장됨
}

process() 메서드는 템플릿으로, 작업 순서를 정의합니다. 서브클래스는 readData()processData()를 differently 구현하며, 필요에 따라 saveData()를 재정의할 수 있습니다. 핵심 이점은 개별 단계에서는 유연성을 허용하면서도 algorithm의 구조가 모든 구현에서 일관되게 유지된다는 것입니다.

challenge icon

챌린지

쉬움

Template Method 패턴을 사용하여 보고서 생성 시스템을 만들어 봅시다! 다양한 유형의 보고서가 동일한 전체 구조를 따르지만, 각 보고서 유형이 data 수집 및 출력 형식 지정과 같은 특정 단계를 사용자 지정하는 프레임워크를 만들게 됩니다.

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

  • report_generator.dart: 이 파일에는 abstract 기본 클래스와 Concrete 보고서 구현이 포함됩니다. ReportGenerator라는 abstract class를 만들고, 다음 순서로 보고서 생성 workflow를 정의하는 generate()라는 Template Method를 작성합니다: fetchData(), analyzeData(), formatReport(), deliver(). fetchData()formatReport() 메서드는 abstract여야 하며(각 보고서 유형이 이를 differently 처리함), analyzeData()Analyzing data...를 출력하고 deliver()는 기본 implementation으로 Report delivered via email.을 출력해야 합니다. 그런 다음 두 개의 Concrete 보고서 클래스를 만듭니다:
    • SalesReport - 해당 fetchData()Fetching sales data from database...를 출력하고, 해당 formatReport()Formatting as bar charts and tables.을 출력합니다.
    • InventoryReport - 해당 fetchData()Fetching inventory levels from warehouse...를 출력하고, 해당 formatReport()Formatting as inventory list.를 출력하며, deliver()를 override하여 Report sent to warehouse manager.를 출력합니다.
  • main.dart: report generator 파일을 import하고, Template Method 패턴이 사용자 지정을 허용하면서도 algorithm 구조를 일관되게 유지하는 방식을 보여 줍니다. SalesReport를 Create하고 해당 generate() 메서드를 call합니다. 그런 다음 구분을 위해 empty 줄을 출력합니다. InventoryReport를 Create하고 해당 generate() 메서드도 call합니다.

두 보고서가 동일한 네 단계 process를 따르지만, 각 보고서의 specific purpose에 중요한 단계는 각각 customize한다는 점에 주목하세요. InventoryReport는 기본 delivery method를 override하여 다른 recipient에게 보고서를 보내기도 합니다!

Expected output:

Fetching sales data from database...
Analyzing data...
Formatting as bar charts and tables.
Report delivered via email.

Fetching inventory levels from warehouse...
Analyzing data...
Formatting as inventory list.
Report sent to warehouse manager.

직접 해보기

import 'report_generator.dart';

void main() {
  // TODO: SalesReport를 생성하고 generate() 메서드를 호출하세요

  // TODO: 구분을 위해 빈 줄을 출력하세요

  // TODO: InventoryReport를 생성하고 generate() 메서드를 호출하세요
}
quiz icon실력 점검

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

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

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