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.
Défi
FacileConstruisons 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 abstraiteReportGeneratoravec une méthode template appeléegenerate()qui définit le flux de génération de rapport dans cet ordre :fetchData(),analyzeData(),formatReport(), etdeliver(). Les méthodesfetchData()etformatReport()doivent être abstraites (chaque type de rapport les gère différemment), tandis queanalyzeData()doit afficherAnalyzing data...etdeliver()doit afficherReport delivered via email.comme implémentations par défaut. Ensuite, créez deux classes de rapport concrètes :SalesReport- sa méthodefetchData()afficheFetching sales data from database...et sa méthodeformatReport()afficheFormatting as bar charts and tables.InventoryReport- sa méthodefetchData()afficheFetching inventory levels from warehouse..., sa méthodeformatReport()afficheFormatting as inventory list., et elle surchargedeliver()pour afficherReport 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 unSalesReportet appelez sa méthodegenerate(). Ensuite, affichez une ligne vide pour la séparation. Créez unInventoryReportet appelez également sa méthodegenerate().
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()
}
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
1Les bases de la POO
Fichiers externesBibliothèques et importsIntroduction à la POOClasses vs ObjetsLe mot-clé thisMéthodesVariables d'instanceBases des constructeursRécapitulatif - Calculatrice simple4Null Safety
Introduction à la Null SafetyNullable vs Non-NullableLes opérateurs ? et !Le mot-clé late et la Null SafetyLes opérateurs Null-AwareLa Null Safety dans les classesRécapitulatif - Système de profil utilisateur7Classes abstraites et Interfaces
Classes abstraitesMéthodes abstraitesInterfaces en DartInterfaces implicitesImplémentation vs ExtensionInterfaces multiplesRécapitulatif - Calculateur de formes10Collections et Génériques
Aperçu des List, Set et MapCollections Type-SafeClasses génériquesMéthodes génériquesContraintes de généricitéIterable & IteratorRécapitulatif - Stockage générique2Les constructeurs en Dart
Constructeur par défautConstructeurs nommésListes d'initialisationConstructeurs constantsConstructeurs factoryConstructeurs de redirectionRécapitulatif - Shape Builder5Encapsulation
Membres publics vs privésLa convention du préfixe _Visibilité au niveau de la bibliothèqueApprofondissement des Getters & SettersMasquage d'informationsRécapitulatif - Dossiers d'étudiants8Mixins
Introduction aux MixinsCréation de MixinsUtilisation de plusieurs MixinsLe mot-clé on dans les MixinsMixin vs HéritageMixin vs InterfaceRécapitulatif - Système Animal11Méthodes spéciales
Redéfinition de toString()Redéfinition de hashCode & ==Interface ComparableMéthode call()Redéfinition de noSuchMethodRécapitulatif - Collection personnalisée14Patrons de conception Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron ObservateurPatron Stratégie3Propriétés de classe
Membres d'instance vs statiquesChamps Final & ConstVariables LateMéthodes et champs statiquesGetters et SettersRécapitulatif - Gestionnaire de compte bancaire6Héritage
Bases de l'héritageLe mot-clé superRedéfinition de méthodeL'annotation @overrideLe mot-clé final pour les classesConstructeurs et héritageRécapitulatif - Hiérarchie des employés9Polymorphisme
Bases du polymorphismePolymorphisme via les interfacesVérification de type à l'exécutionLes opérateurs is & asMot-clé covariantRécapitulatif - Processeur de paiement12POO Asynchrone
Futures & async/awaitBases des StreamsStream ControllersConstructeurs asynchronesL'asynchrone dans les méthodes de classeRécapitulatif - Data Fetcher15Patrons de conception Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode ModèlePatron ÉtatPatron CompositePatron Repository