Design Patterns in Dart: Template Method Pattern

Template Method Pattern – a behavioral design pattern that defines the skeleton of an algorithm in a base class while allowing subclasses to override certain steps without changing the overall flow.


What is the Template Method Pattern?

The Template Method Pattern is about defining an algorithm’s structure once, but letting subclasses change specific parts.

Think of it like a recipe:

  • The base class defines the sequence of steps (mix ingredients → bake → serve).
  • Subclasses can override how each step is done (chocolate cake vs. fruit cake).

When to Use It?

  • When you want common logic across multiple classes but allow flexibility in certain steps.
  • When an algorithm has a fixed structure but details vary.
  • To avoid duplicate code in subclasses.

Example in Dart: Data Exporter

Let’s say we’re building an app that exports reports.

  • The export process always follows the same steps:
    1. Fetch data
    2. Format data
    3. Save to file
  • But subclasses decide how to format (JSON, CSV, XML).

Step 1: Abstract Class with Template Method

abstract class DataExporter {
  // Template Method: defines the algorithm
  void export() {
    fetchData();
    var data = formatData();
    saveFile(data);
  }

  // Steps that can vary
  void fetchData() {
    print("Fetching data from database...");
  }

  String formatData(); // abstract, must be implemented

  void saveFile(String data) {
    print("Saving file with content:\n$data");
  }
}

Step 2: Concrete Implementations

class JsonExporter extends DataExporter {
  @override
  String formatData() {
    return '{"report": "This is JSON formatted report"}';
  }
}

class CsvExporter extends DataExporter {
  @override
  String formatData() {
    return "report,This is CSV formatted report";
  }
}

class XmlExporter extends DataExporter {
  @override
  String formatData() {
    return "<report>This is XML formatted report</report>";
  }
}

Step 3: Client Code

void main() {
  DataExporter jsonExporter = JsonExporter();
  DataExporter csvExporter = CsvExporter();
  DataExporter xmlExporter = XmlExporter();

  print("---- JSON Export ----");
  jsonExporter.export();

  print("\n---- CSV Export ----");
  csvExporter.export();

  print("\n---- XML Export ----");
  xmlExporter.export();
}

Example Output

---- JSON Export ----
Fetching data from database...
Saving file with content:
{"report": "This is JSON formatted report"}

---- CSV Export ----
Fetching data from database...
Saving file with content:
report,This is CSV formatted report

---- XML Export ----
Fetching data from database...
Saving file with content:
<report>This is XML formatted report</report>

Benefits of Template Method Pattern

  • Promotes code reuse (common algorithm in base class).
  • Enforces a consistent process across subclasses.
  • Easy to extend: just add new subclasses for new behaviors.

Drawbacks

  • Can lead to an inflexible inheritance hierarchy.
  • Changes in the base class affect all subclasses.
  • Sometimes strategy pattern is better if behaviors need to be swapped dynamically.

Flutter Use Cases

  • Form validation: Define a generic validation process, let subclasses handle specific field rules.
  • Widget rendering: Define a rendering lifecycle, override custom paint steps.
  • Data persistence: Define save/load flow, change serialization details.

Summary Table

AttributeTemplate Method Pattern
PurposeDefine algorithm skeleton, vary details
Common Use CasesExporters, parsers, workflows
Easy in Dart?Yes, with abstract classes & override
Useful in Flutter?For forms, data flows, widget lifecycles

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Lên đầu trang