Menu
Coddy logo textTech

Pattern Template Method

Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 97 di 110.

Il pattern Template Method definisce lo scheletro di un algoritmo in una classe base, consentendo alle sottoclassi di sovrascrivere passaggi specifici senza modificare la struttura complessiva. La classe base controlla il flusso di lavoro, mentre le sottoclassi personalizzano i singoli passaggi.

Questo schema utilizza l’ereditarietà: una classe astratta definisce un metodo modello che richiama una sequenza di passaggi, alcuni dei quali sono astratti (devono essere implementati dalle sottoclassi) e altri hanno implementazioni predefinite:

abstract class DataProcessor {
  // Metodo template - definisce la struttura dell'algoritmo
  void process() {
    readData();
    processData();
    saveData();
  }

  void readData();      // Astratto - le sottoclassi devono implementarlo
  void processData();   // Astratto - le sottoclassi devono implementarlo

  void saveData() {     // Implementazione predefinita
    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();
  // Lettura del file CSV
  // Analisi delle righe CSV
  // Dati salvati nel database

  var json = JsonProcessor();
  json.process();
  // Lettura del file JSON
  // Analisi degli oggetti JSON
  // Salvato nell'archivio cloud
}

Il metodo process() è il modello: definisce l’ordine delle operazioni. Le sottoclassi implementano readData() e processData() in modo diverso e possono, facoltativamente, sovrascrivere saveData(). Il vantaggio principale è che la struttura dell’algoritmo rimane coerente in tutte le implementazioni, consentendo al contempo flessibilità nei singoli passaggi.

challenge icon

Sfida

Facile

Costruiamo un sistema di generazione di report usando il pattern Template Method! Creerai un framework in cui diversi tipi di report seguono la stessa struttura generale, ma ogni tipo di report personalizza passaggi specifici come la raccolta dei dati e la formattazione dell'output.

Organizzerai il codice in due file:

  • report_generator.dart: questo file contiene la classe base astratta e le implementazioni concrete dei report. Crea una classe astratta ReportGenerator con un metodo template chiamato generate() che definisce il flusso di generazione del report in quest'ordine: fetchData(), analyzeData(), formatReport() e deliver(). I metodi fetchData() e formatReport() devono essere astratti (ogni tipo di report li gestisce in modo diverso), mentre analyzeData() deve stampare Analyzing data... e deliver() deve stampare Report delivered via email. come implementazioni predefinite. Poi crea due classi concrete per i report:
    • SalesReport - il suo fetchData() stampa Fetching sales data from database... e il suo formatReport() stampa Formatting as bar charts and tables.
    • InventoryReport - il suo fetchData() stampa Fetching inventory levels from warehouse..., il suo formatReport() stampa Formatting as inventory list. e sovrascrive deliver() per stampare Report sent to warehouse manager.
  • main.dart: importa il file del generatore di report e mostra come il pattern Template Method mantiene coerente la struttura dell'algoritmo consentendo al contempo la personalizzazione. Crea un SalesReport e chiama il suo metodo generate(). Poi stampa una riga vuota come separazione. Crea anche un InventoryReport e chiama il suo metodo generate().

Nota come entrambi i report seguano lo stesso processo in quattro passaggi, ma ciascuno personalizzi i passaggi rilevanti per il proprio scopo specifico. InventoryReport sovrascrive persino il metodo di consegna predefinito per inviare i report a un destinatario diverso!

Output previsto:

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.

Provalo tu

import 'report_generator.dart';

void main() {
  // TODO: Crea un SalesReport e chiama il suo metodo generate()

  // TODO: Stampa una riga vuota per separare

  // TODO: Crea un InventoryReport e chiama il suo metodo generate()
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Dart online