Modèles de conception en PHP : techniques avancées avec exemples de code
Les modèles de conception sont des solutions éprouvées aux problèmes typiques rencontrés lors du développement de logiciels. Si vous maîtrisez déjà les modèles de base (Singleton, Factory, Observer), il est temps de passer au niveau supérieur. Dans cet article, nous analyserons quatre modèles comportementaux avancés en PHP : Stratégie, Commande, État et Chaîne de responsabilité. Vous découvrirez comment ils aident à écrire un code flexible, maintenable et évolutif.
1. Modèle Stratégie (Strategy)
Le modèle Stratégie permet de définir une famille d'algorithmes, d'encapsuler chacun d'eux et de les rendre interchangeables. Cela est particulièrement utile lorsque vous avez plusieurs façons d'effectuer une même tâche et que vous souhaitez basculer facilement entre elles sans modifier la classe principale.
Quand l'utiliser :
- Vous avez plusieurs variantes d'algorithmes qui peuvent changer pendant l'exécution.
- Vous souhaitez éviter des constructions conditionnelles lourdes (if-else ou switch).
- Les algorithmes peuvent être réutilisés dans différentes parties de l'application.
Exemple : système de calcul des frais de livraison
Imaginez que vous avez une boutique en ligne et que les frais de livraison dépendent du transporteur choisi : La Poste russe, DHL ou un service de coursier.
<?php
// Interface de stratégieinterface ShippingStrategy { public function calculate(float $weight, float $distance): float;}
// Stratégies concrètesclass RussianPostShipping implements ShippingStrategy { public function calculate(float $weight, float $distance): float { return ($weight * 0.5) + ($distance * 0.1); }}
class DHLShipping implements ShippingStrategy { public function calculate(float $weight, float $distance): float { return ($weight * 1.2) + ($distance * 0.3) + 10; }}
class CourierShipping implements ShippingStrategy { public function calculate(float $weight, float $distance): float { return ($weight * 0.8) + ($distance * 0.2) + 5; }}
// Contexteclass Order { private float $weight; private float $distance; private ShippingStrategy $strategy;
public function __construct(float $weight, float $distance, ShippingStrategy $strategy) { $this->weight = $weight; $this->distance = $distance; $this->strategy = $strategy; }
public function setStrategy(ShippingStrategy $strategy): void { $this->strategy = $strategy; }
public function getShippingCost(): float { return $this->strategy->calculate($this->weight, $this->distance); }}
// Utilisation$order = new Order(2.5, 100, new RussianPostShipping());echo "Livraison par La Poste russe : " . $order->getShippingCost() . " roubles.";
$order->setStrategy(new DHLShipping());echo "Livraison par DHL : " . $order->getShippingCost() . " roubles.";?>Dans cet exemple, nous changeons facilement l'algorithme de calcul des coûts sans toucher à la classe Order. L'ajout d'un nouveau transporteur se résume à créer une nouvelle classe implémentant l'interface ShippingStrategy.
2. Modèle Commande (Command)
Le modèle Commande transforme les requêtes en objets, permettant de paramétrer les clients avec différentes requêtes, de mettre les requêtes en file d'attente, de les journaliser ou de prendre en charge l'annulation des opérations.
Quand l'utiliser :
- Vous devez implémenter l'annulation (undo) et la répétition (redo) des opérations.
- Vous devez mettre les opérations en file d'attente ou les exécuter de manière asynchrone.
- Vous souhaitez séparer l'expéditeur de la requête de son destinataire.
Exemple : éditeur de texte avec annulation d'actions
<?php
// Interface de commandeinterface Command { public function execute(): void; public function undo(): void;}
// Récepteur (Receiver)class