Template Method Pattern vs Factory Method Pattern vs Strategy Pattern
1. Template Method Pattern
- Structure commune avec étapes personnalisables : Permet de définir la structure d’un algorithme avec certaines étapes personnalisables dans les sous-classes.
- Logique centralisée avec variation spécifique : La logique commune est centralisée, tandis que les étapes spécifiques sont déléguées aux sous-classes.
- Exemple : Dans la génération de documents PDF, CSV ou JSON, le processus général (préparation des données, formatage et exportation) est fixe, mais le formatage et l'exportation sont définis par chaque sous-classe.
2. Factory Method Pattern
- Instanciation déléguée aux sous-classes : Le client ne sait pas quelle classe concrète va être instanciée, il appelle une méthode
factory()qui détermine quel objet créer. - Création centralisée et extensible : La logique de création est centralisée dans des factories, ce qui permet d’ajouter de nouvelles classes sans toucher au code client.
- Exemple : Génération de documents PDF, CSV ou JSON via des classes factories, où la méthode factory retourne l’objet de document nécessaire en fonction de la demande.
3. Strategy Pattern
- Algorithmes interchangeables : Permet de choisir dynamiquement entre plusieurs algorithmes sans changer le code client.
- Encapsulation d’algorithmes : Chaque algorithme est encapsulé dans une stratégie distincte, ce qui permet d'en changer facilement au moment de l’exécution.
- Exemple : Sélection dynamique du format de document (PDF, CSV, JSON) pour générer le document en fonction de la méthode choisie par l'utilisateur.
Comparaison directe :
| Caractéristique | Template Method Pattern | Factory Method Pattern | Strategy Pattern |
|---|---|---|---|
| Objectif principal | Structurer un algorithme avec des étapes modifiables | Déléguer la création d'objets à des sous-classes | Permettre le choix dynamique entre plusieurs algorithmes |
| Flexibilité dans l’ajout de classes | Moyenne, nécessite la création de nouvelles sous-classes | Forte, ajouter une nouvelle classe de produit est simple | Très flexible, on peut ajouter de nouvelles stratégies sans toucher au code client |
| Changement dynamique | Non, les étapes sont fixes | Non, l'objet est déterminé au moment de la création | Oui, la stratégie peut être changée dynamiquement à l'exécution |
| Responsabilité du client | Le client connaît la structure de l’algorithme | Le client demande simplement un objet sans connaître sa classe concrète | Le client choisit la stratégie à utiliser |
| Exemple d'application | Génération de documents avec étapes fixes mais formatage variable | Génération de documents en fonction du type demandé | Choix dynamique du type de document à générer |
Exemples
1. Template Method Pattern
Dans cet exemple, le processus général de génération de documents est défini dans une classe de base, mais les sous-classes (PDF, CSV, JSON) modifient le formatage et l'exportation des données :
abstract class DocumentGenerator
{
public function generate($data)
{
$preparedData = $this->prepareData($data);
$formattedData = $this->format($preparedData);
$this->export($formattedData);
}
protected function prepareData($data) {
return collect($data)->sort();
}
abstract protected function format($data);
abstract protected function export($formattedData);
}
class PdfDocument extends DocumentGenerator
{
protected function format($data) {
return "PDF formatted data";
}
protected function export($formattedData) {
echo "Exporting PDF document.";
}
}
class CsvDocument extends DocumentGenerator
{
protected function format($data) {
return "CSV formatted data";
}
protected function export($formattedData) {
echo "Exporting CSV document.";
}
}
class JsonDocument extends DocumentGenerator
{
protected function format($data) {
return "JSON formatted data";
}
protected function export($formattedData) {
echo "Exporting JSON document.";
}
}
2. Factory Method Pattern
Ici, une méthode factory détermine quel type de document générer (PDF, CSV, ou JSON) sans que le client connaisse la classe concrète :
abstract class DocumentFactory
{
abstract public function createDocument();
public function generateDocument($data)
{
$document = $this->createDocument();
return $document->generate($data);
}
}
class PdfFactory extends DocumentFactory
{
public function createDocument() {
return new PdfDocument();
}
}
class CsvFactory extends DocumentFactory
{
public function createDocument() {
return new CsvDocument();
}
}
class JsonFactory extends DocumentFactory
{
public function createDocument() {
return new JsonDocument();
}
}
// Utilisation
$factory = new PdfFactory();
$factory->generateDocument($data);
3. Strategy Pattern
Le Strategy Pattern permet de choisir dynamiquement la stratégie de génération de documents en fonction du format souhaité (PDF, CSV, JSON) :
interface DocumentStrategy
{
public function generate($data);
}
class PdfStrategy implements DocumentStrategy
{
public function generate($data) {
return "Generating PDF document.";
}
}
class CsvStrategy implements DocumentStrategy
{
public function generate($data) {
return "Generating CSV document.";
}
}
class JsonStrategy implements DocumentStrategy
{
public function generate($data) {
return "Generating JSON document.";
}
}
class DocumentContext
{
protected $strategy;
public function setStrategy(DocumentStrategy $strategy) {
$this->strategy = $strategy;
}
public function executeStrategy($data) {
return $this->strategy->generate($data);
}
}
// Utilisation
$context = new DocumentContext();
$context->setStrategy(new PdfStrategy());
$context->executeStrategy($data);
Explications
Dans le Template Method Pattern, la structure générale de la génération de documents (préparation, formatage, exportation) est définie dans une classe de base. Les sous-classes modifient uniquement certaines étapes comme le formatage des données ou leur exportation.
Le Factory Method Pattern délègue la création des objets PDF, CSV, ou JSON à des sous-classes responsables de renvoyer les bonnes instances, mais le client ne connaît jamais la classe concrète utilisée.
Le Strategy Pattern permet de choisir dynamiquement entre plusieurs algorithmes de génération de documents. Le client peut sélectionner et changer de stratégie (PDF, CSV, JSON) à tout moment.
Cas d'utilisation des patterns
Le Template Method Pattern est utile lorsque tu veux garder la structure générale de ton algorithme fixe, mais permettre des variations dans certaines étapes spécifiques. Ici, la génération de documents avec un processus constant (préparation des données, formatage et exportation) mais avec des détails différents selon le format (PDF, CSV, JSON) en est un bon exemple.
Le Factory Method Pattern est particulièrement adapté lorsque tu veux centraliser et simplifier la création d’objets tout en gardant la flexibilité d’ajouter de nouveaux types d'objets. Il est idéal pour des situations où l’objet à créer peut varier, mais où le code client ne doit pas être alourdi avec des détails de création d’instances concrètes.
Le Strategy Pattern est approprié lorsque tu as besoin de choisir dynamiquement entre plusieurs algorithmes interchangeables pour accomplir une tâche similaire, comme ici, le choix de la stratégie de génération de documents selon le format demandé par l’utilisateur.
Conclusion
- Le Template Method Pattern est utile pour structurer un processus global tout en permettant des variations dans les sous-classes.
- Le Factory Method Pattern centralise la création d'objets et rend le système plus extensible sans affecter le client.
- Le Strategy Pattern apporte de la flexibilité en permettant de choisir ou changer dynamiquement entre plusieurs algorithmes encapsulés.
Ces trois patterns offrent des solutions élégantes pour organiser et modulariser la génération de documents dans des formats variés (PDF, CSV, JSON) selon des besoins différents.