Patron Méthode Modèle
Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy — leçon 78 sur 91.
Le Patron de méthode (Template Method Pattern) est un patron de conception comportemental qui définit le squelette d'un algorithme dans une classe de base, permettant aux sous-classes de redéfinir des étapes spécifiques sans changer la structure globale. La classe de base contrôle le flux de travail, tandis que les sous-classes personnalisent les éléments individuels.
Envisagez de créer différents types de documents.
Chaque document suit le même processus : créer l'en-tête, ajouter du contenu, créer le pied de page. Mais les spécificités de chaque étape varient selon le type de document. Le patron de méthode définit cette séquence, tandis que les sous-classes implémentent les détails.
<?php
abstract class DocumentGenerator {
// La méthode template - définit la structure de l'algorithme
public final function generate(): string {
$output = $this->createHeader();
$output .= $this->createContent();
$output .= $this->createFooter();
return $output;
}
// Étapes à implémenter par les sous-classes
abstract protected function createHeader(): string;
abstract protected function createContent(): string;
abstract protected function createFooter(): string;
}
class HtmlDocument extends DocumentGenerator {
protected function createHeader(): string {
return "<html><head></head><body>";
}
protected function createContent(): string {
return "<p>Hello World</p>";
}
protected function createFooter(): string {
return "</body></html>";
}
}
class TextDocument extends DocumentGenerator {
protected function createHeader(): string {
return "=== DOCUMENT ===\n";
}
protected function createContent(): string {
return "Hello World\n";
}
protected function createFooter(): string {
return "=== END ===";
}
}
$html = new HtmlDocument();
echo $html->generate() . "\n";
$text = new TextDocument();
echo $text->generate();
Résultat :
<html><head></head><body><p>Hello World</p></body></html>
=== DOCUMENT ===
Hello World
=== END ===Remarquez le mot-clé final sur la méthode template. Cela empêche les sous-classes de modifier la structure de l'algorithme. Ce patron est idéal lorsque vous avez plusieurs classes qui suivent le même flux de travail mais diffèrent dans les détails d'implémentation. Ajouter un nouveau type de document signifie créer une nouvelle sous-classe sans toucher au code existant.
Défi
FacileConstruisons un système de génération de rapports en utilisant le Template Method Pattern. Différents types de rapports suivent la même structure — une section de titre, une section de données et une section de résumé — mais chaque type de rapport formate ces sections différemment. La méthode template définira ce flux de travail tandis que les sous-classes personnaliseront chaque étape.
Vous organiserez votre code sur quatre fichiers :
ReportGenerator.php— Créez une classe abstraiteReportGeneratorqui définit le squelette de l'algorithme de génération de rapport. Votre classe doit :- Accepter un titre de rapport dans son constructeur (utilisez la promotion de constructeur)
- Avoir une méthode publique
finalnomméegenerate(): stringqui appelle trois étapes dans l'ordre :createTitle(),createBody(), etcreateSummary(), en concaténant leurs résultats - Déclarer trois méthodes protégées abstraites que les sous-classes doivent implémenter :
createTitle(): string,createBody(): string, etcreateSummary(): string
HtmlReport.php— Incluez le fichier ReportGenerator et créez une classeHtmlReportqui l'étend. Ce rapport formate la sortie en HTML :createTitle()retourne"<h1>" . $this->title . "</h1>"createBody()retourne"<p>Report data goes here</p>"createSummary()retourne"<footer>End of report</footer>"
PlainTextReport.php— Incluez le fichier ReportGenerator et créez une classePlainTextReportqui l'étend. Ce rapport utilise un formatage de texte simple :createTitle()retourne"### " . $this->title . " ###\n"createBody()retourne"Report data goes here\n"createSummary()retourne"--- End of report ---"
main.php— Incluez les deux fichiers de rapport. Vous recevrez deux entrées : un type de rapport ("html"ou"text") et un titre de rapport.En fonction du type de rapport, créez le générateur de rapport approprié avec le titre donné. Appelez
generate()et affichez le rapport complet.
Le Template Method Pattern garantit que tous les rapports suivent la même structure en trois étapes tout en permettant à chaque type de rapport de formater ses sections de manière unique. Le mot-clé final sur generate() empêche les sous-classes de modifier la séquence de l'algorithme — elles ne peuvent que personnaliser les étapes individuelles.
Aide-mémoire
Le Template Method Pattern (Patron de Méthode de Gabarit) 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 contient une méthode de gabarit (template method) qui contrôle la séquence du flux de travail. Cette méthode est généralement marquée comme final pour empêcher les sous-classes de modifier la structure de l'algorithme.
Les sous-classes implémentent des méthodes abstraites pour personnaliser les étapes individuelles de l'algorithme.
<?php
abstract class DocumentGenerator {
// Méthode de gabarit - définit la structure de l'algorithme
public final function generate(): string {
$output = $this->createHeader();
$output .= $this->createContent();
$output .= $this->createFooter();
return $output;
}
// Étapes abstraites à implémenter par les sous-classes
abstract protected function createHeader(): string;
abstract protected function createContent(): string;
abstract protected function createFooter(): string;
}
class HtmlDocument extends DocumentGenerator {
protected function createHeader(): string {
return "<html><head></head><body>";
}
protected function createContent(): string {
return "<p>Hello World</p>";
}
protected function createFooter(): string {
return "</body></html>";
}
}
$html = new HtmlDocument();
echo $html->generate();
Caractéristiques clés :
- La méthode de gabarit est marquée
finalpour empêcher la modification de la structure de l'algorithme - Les méthodes abstraites définissent des points de personnalisation pour les sous-classes
- Idéal lorsque plusieurs classes suivent le même flux de travail mais diffèrent dans les détails d'implémentation
- L'ajout de nouvelles variantes nécessite uniquement la création de nouvelles sous-classes sans modifier le code existant
Essayez vous-même
<?php
require_once 'HtmlReport.php';
require_once 'PlainTextReport.php';
// Lire l'entrée
$reportType = trim(fgets(STDIN));
$reportTitle = trim(fgets(STDIN));
// TODO: En fonction du type de rapport ("html" ou "text"),
// créer le générateur de rapport approprié avec le titre donné
// TODO: Appeler generate() et afficher le rapport complet
?>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 externesIntroduction à la POOClasses vs ObjetsLe mot-clé $thisMéthodesPropriétésConstructeur (__construct)Destructeur (__destruct)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLe mot-clé parent::Redéfinition de méthodeLe mot-clé finalClasses abstraitesRécapitulatif - Hiérarchie des employés7Encapsulation
Public, Protégé, PrivéModificateurs d'accès en détailGetters et SettersMasquage d'informationPromotion de constructeur (8.0)Récapitulatif - Système de gestion d'étudiants10Concepts avancés de la POO
Composition vs HéritageInjection de dépendancesClasses anonymesÉnumérations (PHP 8.1)Fibers (PHP 8.1)Clonage d'objets : analyse approfondieGénérateurs et Itérateurs13Patrons de conception Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode ModèlePatron ÉtatPatron CompositePatron Repository2Espaces de noms et Autoloading
Introduction aux espaces de nomsLe mot-clé useStandard d'Autoloading PSR-4L'Autoloader ComposerRécapitulatif - Projet organisé5Interfaces et Contrats
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesInterface vs Classe AbstraiteType Hinting avec les InterfacesRécapitulatif - Calculateur de Formes8Méthodes magiques
Introduction aux méthodes magiques__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Clonage d'objets__serialize & __unserializeRécapitulatif - Collection personnalisée3Propriétés de classe
Propriétés d'instance vs Propriétés statiquesConstantes dans les classesMéthodes et propriétés statiquesPropriétés privées et protégéesPropriétés readonly (PHP 8.1)Récapitulatif - Gestionnaire de compte bancaire6Polymorphisme
Retour sur la redéfinition de méthodePolymorphisme via les interfacesType Hinting et Types d'unionLiaison statique tardiveRécapitulatif - Processeur de paiement9Traits
Introduction aux TraitsUtilisation de plusieurs TraitsRésolution des conflits de TraitsMéthodes abstraites dans les TraitsTraits vs Héritage12Patrons de conception Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron ObservateurPatron Stratégie