Menu
Coddy logo textTech

Wzorzec metody szablonowej

Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 97 z 110.

Wzorzec Template Method definiuje szkielet algorytmu w klasie bazowej, umożliwiając podklasom nadpisywanie określonych kroków bez zmiany ogólnej struktury. Klasa bazowa kontroluje przepływ pracy, a podklasy dostosowują poszczególne kroki.

Ten wzorzec wykorzystuje dziedziczenie: klasa abstrakcyjna definiuje metodę szablonową, która wywołuje sekwencję kroków, z których niektóre są abstrakcyjne (muszą zostać zaimplementowane przez podklasy), a niektóre mają domyślne implementacje:

abstract class DataProcessor {
  // Metoda szablonowa – określa strukturę algorytmu
  void process() {
    readData();
    processData();
    saveData();
  }

  void readData();      // Abstrakcyjna – podklasy muszą ją zaimplementować
  void processData();   // Abstrakcyjna – podklasy muszą ją zaimplementować

  void saveData() {     // Domyślna implementacja
    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();
  // Odczytywanie pliku CSV
  // Przetwarzanie wierszy CSV
  // Dane zapisano w bazie danych

  var json = JsonProcessor();
  json.process();
  // Odczytywanie pliku JSON
  // Przetwarzanie obiektów JSON
  // Zapisano w chmurze
}

Metoda process() jest szablonem — określa kolejność operacji. Podklasy implementują readData() i processData() w różny sposób, a opcjonalnie mogą przesłonić saveData(). Główną zaletą jest to, że struktura algorytmu pozostaje spójna we wszystkich implementacjach, a poszczególne kroki można dostosowywać.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system generowania raportów z użyciem wzorca metody szablonowej! Stworzysz szkielet, w którym różne typy raportów mają tę samą ogólną strukturę, ale każdy typ raportu dostosowuje określone kroki, takie jak pobieranie danych i formatowanie wyniku.

Podzielisz kod na dwa pliki:

  • report_generator.dart: Ten plik zawiera abstrakcyjną klasę bazową oraz konkretne implementacje raportów. Utwórz klasę abstrakcyjną ReportGenerator z metodą szablonową o nazwie generate(), która definiuje proces generowania raportu w następującej kolejności: fetchData(), analyzeData(), formatReport() i deliver(). Metody fetchData() i formatReport() powinny być abstrakcyjne (każdy typ raportu obsługuje je inaczej), natomiast analyzeData() powinna wypisywać Analyzing data..., a deliver() powinna wypisywać Report delivered via email. jako domyślne implementacje. Następnie utwórz dwie konkretne klasy raportów:
    • SalesReport — jej metoda fetchData() wypisuje Fetching sales data from database..., a metoda formatReport() wypisuje Formatting as bar charts and tables.
    • InventoryReport — jej metoda fetchData() wypisuje Fetching inventory levels from warehouse..., metoda formatReport() wypisuje Formatting as inventory list., a metoda deliver() jest nadpisana tak, aby wypisywać Report sent to warehouse manager.
  • main.dart: Zaimportuj plik generatora raportów i pokaż, jak wzorzec metody szablonowej pozwala zachować spójną strukturę algorytmu, a jednocześnie umożliwia jej dostosowanie. Utwórz obiekt SalesReport i wywołaj jego metodę generate(). Następnie wypisz pusty wiersz, aby oddzielić wyniki. Utwórz obiekt InventoryReport i również wywołaj jego metodę generate().

Zwróć uwagę, że oba raporty wykonują ten sam czteroetapowy proces, ale każdy dostosowuje kroki istotne dla swojego konkretnego celu. Klasa InventoryReport nadpisuje nawet domyślną metodę dostarczania, aby wysyłać raporty do innego odbiorcy!

Oczekiwany wynik:

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.

Spróbuj swoich sił

import 'report_generator.dart';

void main() {
  // TODO: Utwórz SalesReport i wywołaj jego metodę generate()

  // TODO: Wypisz pustą linię, aby oddzielić wyniki

  // TODO: Utwórz InventoryReport i wywołaj jego metodę generate()
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Dart online