Modèles de conception en PHP : niveau avancé
\n\nLes modèles de conception (design patterns) sont des solutions éprouvées aux problèmes typiques rencontrés lors du développement de logiciels. Au niveau débutant, les développeurs étudient Singleton, Factory ou Adapter. Cependant, dans les systèmes complexes, à forte charge ou flexibles en PHP, des modèles plus puissants et abstraits sont nécessaires. Dans cet article, nous analyserons quatre modèles avancés avec des exemples de code réels en PHP : Stratégie, Méthode Fabrique, Observateur et État.
\n\n1. Modèle "Stratégie" (Strategy)
\n\nObjectif : Définir une famille d'algorithmes, encapsuler chacun d'eux et les rendre interchangeables. Permet de modifier le comportement d'un objet pendant l'exécution sans modifier son code.
\n\nExemple : Système de traitement des paiements. Nous avons plusieurs modes de paiement : carte de crédit, PayPal, crypto-monnaie. Chaque mode a sa propre logique de validation et de traitement.
\n\n<?php\n\n// Interface de stratégie\ninterface PaymentStrategy\n{\n public function pay(float $amount): void;\n public function validate(): bool;\n}\n\n// Stratégies concrètes\nclass CreditCardPayment implements PaymentStrategy\n{\n private string $cardNumber;\n private string $cvv;\n\n public function __construct(string $cardNumber, string $cvv)\n {\n $this->cardNumber = $cardNumber;\n $this->cvv = $cvv;\n }\n\n public function validate(): bool\n {\n // Vérification simple de la longueur du numéro de carte\n return strlen($this->cardNumber) === 16 && strlen($this->cvv) === 3;\n }\n\n public function pay(float $amount): void\n {\n if (!$this->validate()) {\n throw new \\InvalidArgumentException("Données de carte invalides");\n }\n echo "Payé {$amount} via carte de crédit {$this->cardNumber}.<br>";\n }\n}\n\nclass PayPalPayment implements PaymentStrategy\n{\n private string $email;\n\n public function __construct(string $email)\n {\n $this->email = $email;\n }\n\n public function validate(): bool\n {\n return filter_var($this->email, FILTER_VALIDATE_EMAIL) !== false;\n }\n\n public function pay(float $amount): void\n {\n if (!$this->validate()) {\n throw new \\InvalidArgumentException("Email PayPal invalide");\n }\n echo "Payé {$amount} via PayPal ({$this->email}).<br>";\n }\n}\n\n// Contexte (client)\nclass OrderProcessor\n{\n private PaymentStrategy $strategy;\n\n public function setPaymentStrategy(PaymentStrategy $strategy): void\n {\n $this->strategy = $strategy;\n }\n\n public function processOrder(float $total): void\n {\n if (!isset($this->strategy)) {\n throw new \\RuntimeException("Mode de paiement non sélectionné");\n }\n $this->strategy->pay($total);\n }\n}\n\n// Utilisation\n$order = new OrderProcessor();\n$order->setPaymentStrategy(new CreditCardPayment('1234567812345678', '123'));\n$order->processOrder(150.00);\n// Sortie : Payé 150 via carte de crédit 1234567812345678.\n\n?>\n\nAvantages : Facile d'ajouter de nouveaux algorithmes (nouveaux modes de paiement) sans modifier le code existant. Le code devient flexible et testable.
\n\n2. Modèle "Méthode Fabrique" (Factory Method)
\n\nObjectif : Définir une interface pour créer un objet, mais permettre aux sous-classes de modifier le type d'objet créé. C'est le modèle de base pour tous les patrons de création.
\n\nExemple : Génération de différents types de rapports (PDF, HTML, JSON) en fonction de la demande de l'utilisateur.
\n\n<?php\n\n// Produit abstrait\ninterface Report\n{\n public function generate(): string;\n}\n\n// Produits concrets\nclass PdfReport implements Report\n