Menu
Coddy logo textTech

Patron Méthode Modèle

Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy — leçon 97 sur 110.

Le patron Template Method définit le squelette d'un algorithme dans une classe de base, permettant aux sous-classes de redéfinir certaines étapes spécifiques sans modifier la structure globale. La classe de base contrôle le flux de travail, tandis que les sous-classes personnalisent les étapes individuelles.

Ce patron utilise l'héritage : une classe abstraite définit une méthode modèle qui appelle une séquence d'étapes, dont certaines sont abstraites (doivent être implémentées par les sous-classes) et d'autres ont des implémentations par défaut :

abstract class DataProcessor {
  // Méthode template - définit la structure de l'algorithme
  void process() {
    readData();
    processData();
    saveData();
  }

  void readData();      // Abstrait - les sous-classes doivent implémenter
  void processData();   // Abstrait - les sous-classes doivent implémenter

  void saveData() {     // Implémentation par défaut
    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();
  // Lecture du fichier CSV
  // Analyse des lignes CSV
  // Données sauvegardées dans la base de données

  var json = JsonProcessor();
  json.process();
  // Lecture du fichier JSON
  // Analyse des objets JSON
  // Sauvegardé dans le stockage cloud
}

La méthode process() est le modèle - elle définit l'ordre des opérations. Les sous-classes implémentent readData() et processData() différemment, et peuvent éventuellement surcharger saveData(). Le principal avantage est que la structure de l'algorithme reste cohérente à travers toutes les implémentations tout en permettant une certaine flexibilité dans les étapes individuelles.

challenge icon

Défi

Facile

Construisons un système de génération de rapports en utilisant le patron de conception Template Method ! Vous allez créer un framework où différents types de rapports suivent la même structure globale, mais chaque type de rapport personnalise des étapes spécifiques comme la collecte de données et le formatage de la sortie.

Vous organiserez votre code en deux fichiers :

  • report_generator.dart : Ce fichier contient votre classe de base abstraite et les implémentations concrètes des rapports. Créez une classe abstraite ReportGenerator avec une méthode template appelée generate() qui définit le flux de génération de rapport dans cet ordre : fetchData(), analyzeData(), formatReport(), et deliver(). Les méthodes fetchData() et formatReport() doivent être abstraites (chaque type de rapport les gère différemment), tandis que analyzeData() doit afficher Analyzing data... et deliver() doit afficher Report delivered via email. comme implémentations par défaut. Ensuite, créez deux classes de rapport concrètes :
    • SalesReport - sa méthode fetchData() affiche Fetching sales data from database... et sa méthode formatReport() affiche Formatting as bar charts and tables.
    • InventoryReport - sa méthode fetchData() affiche Fetching inventory levels from warehouse..., sa méthode formatReport() affiche Formatting as inventory list., et elle surcharge deliver() pour afficher Report sent to warehouse manager.
  • main.dart : Importez votre fichier de générateur de rapports et démontrez comment le patron Template Method maintient la structure de l'algorithme cohérente tout en permettant la personnalisation. Créez un SalesReport et appelez sa méthode generate(). Ensuite, affichez une ligne vide pour la séparation. Créez un InventoryReport et appelez également sa méthode generate().

Remarquez comment les deux rapports suivent le même processus en quatre étapes, mais chacun personnalise les étapes qui comptent pour son objectif spécifique. Le InventoryReport surcharge même la méthode de livraison par défaut pour envoyer les rapports à un destinataire différent !

Sortie attendue :

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.

Aide-mémoire

Le patron de méthode (Template Method) définit le squelette d'un algorithme dans une classe de base, permettant aux sous-classes de redéfinir certaines étapes sans modifier la structure globale.

Une classe abstraite définit une méthode patron qui appelle une séquence d'étapes. Certaines étapes sont abstraites (doivent être implémentées par les sous-classes) et d'autres ont des implémentations par défaut :

abstract class DataProcessor {
  // Méthode patron - définit la structure de l'algorithme
  void process() {
    readData();
    processData();
    saveData();
  }

  void readData();      // Abstrait - les sous-classes doivent l'implémenter
  void processData();   // Abstrait - les sous-classes doivent l'implémenter

  void saveData() {     // Implémentation par défaut
    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');
}

La méthode patron contrôle l'ordre du flux de travail. Les sous-classes personnalisent les étapes individuelles en implémentant les méthodes abstraites et en remplaçant éventuellement les implémentations par défaut. La structure de l'algorithme reste cohérente à travers toutes les implémentations.

Essayez vous-même

import 'report_generator.dart';

void main() {
  // TODO: Créer un SalesReport et appeler sa méthode generate()

  // TODO: Afficher une ligne vide pour la séparation

  // TODO: Créer un InventoryReport et appeler sa méthode generate()
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet