Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
💥 Du 22 au 24 novembre : Accès 100% GRATUIT
à la Bibliothèque Numérique ENI. Je m'inscris !
  1. Livres et vidéos
  2. Design Patterns en PHP
  3. Le design pattern Template Method
Extrait - Design Patterns en PHP Les 23 modèles de conception : descriptions et solutions illustrées en UML2 et PHP (2e édition)
Extraits du livre
Design Patterns en PHP Les 23 modèles de conception : descriptions et solutions illustrées en UML2 et PHP (2e édition)
2 avis
Revenir à la page d'achat du livre

Le design pattern Template Method

Description

Le design pattern Template Method permet de reporter dans des sous-classes certaines étapes de l’une des opérations d’un objet, ces étapes étant alors décrites dans les sous-classes.

Exemple

Au sein du système de vente en ligne de véhicules, nous gérons des commandes passées par des clients en France et au Luxembourg. La différence entre ces deux types de commandes concerne le calcul de la TVA. Si en France le taux de TVA est de 20 %, il existe quatre taux de TVA au Luxembourg (pour des raisons de simplification, nous prendrons comme base le taux standard de 17 %). Le calcul de la TVA demande donc deux opérations de calcul distinctes en fonction du pays.

Une première solution consiste à implémenter deux classes distinctes sans surclasse commune : CommandeFrance et CommandeLuxembourg. Cette solution présente l’inconvénient majeur d’avoir du code identique mais qui n’a pas été factorisé, comme l’affichage des informations de la commande (méthode affiche).

Une classe abstraite Commande peut être introduite pour factoriser les méthodes communes comme la méthode affiche.

Le design pattern Template Method permet d’aller plus loin en proposant de factoriser du code commun au sein des méthodes. Nous prenons l’exemple de la méthode calculeMontantTtc dont l’algorithme est le suivant pour la France (en pseudo-code).

calculeMontantTtc : 
montantTva = montantHt * 0,2; 
montantTtc = montantHt + montantTva; 

L’algorithme pour le Luxembourg...

Structure

1. Diagramme de classes

La figure 27.4 montre la structure générique du design pattern Template Method.

Structure du design pattern Template Method

Figure 27.4 - Structure du design pattern Template Method

2. Participants

Les participants au design pattern Template Method sont les suivants :

  • La classe abstraite ClasseAbstraite (AbstractCommande) contient la méthode "modèle" ainsi que la signature des méthodes abstraites que cette méthode invoque.

  • La sous-classe concrète ClasseConcrete (CommandeFrance et CommandeLuxembourg) implémente les méthodes abstraites utilisées par la méthode "modèle" de la classe abstraite. Il peut y avoir plusieurs classes concrètes.

3. Collaborations

L’implémentation de l’algorithme est réalisée par la collaboration entre la méthode "modèle" de la classe abstraite et les méthodes d’une sous-classe concrète qui complètent l’algorithme.

Domaines d’application

Le design pattern Template Method est utilisé dans les cas suivants :

  • Une classe partage avec une autre ou plusieurs autres classes du code identique qui peut être factorisé après que la ou les parties spécifiques à chaque classe aient été déplacées dans de nouvelles méthodes.

  • Un algorithme possède une partie invariable et des parties spécifiques à différents types d’objets.

Exemple en PHP

La classe abstraite AbstractCommande contient la méthode "modèle" calculeMontantTtc qui invoque la méthode abstraite calculeTva.

<?php 
 
declare(strict_types=1); 
 
namespace ENI\DesignPatterns\TemplateMethod; 
 
abstract class AbstractCommande 
{ 
   protected float $montantHt; 
 
   protected float $montantTva; 
 
   protected float $montantTtc; 
 
   public function __construct(float $montantHt) 
   { 
       $this->montantHt = $montantHt; 
   } 
 
   public function calculeMontantTtc(): void 
   { 
       $this->calculeTva(); 
       $this->montantTtc = $this->montantHt + $this->montantTva; 
   } 
 
   public function affiche(): void 
   { 
       echo 'Commande' . PHP_EOL; 
       echo 'Montant HT ' . $this->formateMontant($this->montantHt) . 
PHP_EOL; 
       echo 'Montant TTC ' . $this->formateMontant($this->montantTtc) . 
PHP_EOL; 
   } 
 
   protected function formateMontant(float $montant): string 
   { ...