Modèles de conception en PHP : des bases aux techniques avancées
Les modèles de conception (design patterns) sont des solutions éprouvées et réutilisables pour des problèmes courants rencontrés lors du développement logiciel. Pour un développeur PHP, la connaissance des patrons n'est pas simplement une ligne sur un CV, mais un véritable outil pour créer un code flexible, maintenable et évolutif. Dans cet article, nous allons analyser trois groupes clés de patrons GoF (Gang of Four) avec des exemples concrets en PHP que vous pourrez immédiatement appliquer dans vos projets.
1. Patrons de création (Creational Patterns)
Ces patrons gèrent la création d'objets, en masquant la logique d'instanciation et en rendant le système indépendant de la manière dont les objets sont créés et composés.
Singleton (Singleton)
Garantit qu'une classe n'a qu'une seule instance et fournit un point d'accès global à celle-ci. Un exemple classique est la connexion à une base de données.
<?phpclass Database { private static ?Database $instance = null; private PDO $pdo;
private function __construct() { $this->pdo = new PDO('mysql:host=localhost;dbname=test', 'root', ''); }
public static function getInstance(): Database { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; }
public function query(string $sql): array { // Logique d'exécution de la requête return $this->pdo->query($sql)->fetchAll(); }
// Interdire le clonage et la désérialisation private function __clone() {} public function __wakeup() { throw new Exception("Cannot unserialize singleton"); }}
// Utilisation$db = Database::getInstance();$results = $db->query("SELECT * FROM users");?>Méthode Fabrique (Factory Method)
Définit une interface pour créer un objet, mais permet aux sous-classes de modifier le type d'objet créé. Idéal pour créer des familles d'objets liés.
<?phpinterface Logger { public function log(string $message): void;}
class FileLogger implements Logger { public function log(string $message): void { file_put_contents('app.log', $message . PHP_EOL, FILE_APPEND); }}
class DatabaseLogger implements Logger { public function log(string $message): void { // Sauvegarder dans la base de données echo "Logged to DB: $message"; }}
abstract class LoggerFactory { abstract public function createLogger(): Logger;
public function logMessage(string $message): void { $logger = $this->createLogger(); $logger->log($message); }}
class FileLoggerFactory extends LoggerFactory { public function createLogger(): Logger { return new FileLogger(); }}
class DatabaseLoggerFactory extends LoggerFactory { public function createLogger(): Logger { return new DatabaseLogger(); }}
// Utilisation$factory = new FileLoggerFactory();$factory->logMessage("Ce message sera écrit dans le fichier");?>2. Patrons structurels (Structural Patterns)
Ils définissent comment les classes et les objets peuvent être assemblés en structures plus grandes, tout en conservant flexibilité et efficacité.
Adaptateur (Adapter)
Permet à des objets avec des interfaces incompatibles de travailler ensemble. L'adaptateur agit comme une enveloppe qui convertit les appels d'une interface en une autre.
<?php// Ancienne classe avec une interface peu pratiqueclass OldPaymentSystem { public function processPayment(float $amount, string $currency): string { return "Processing $amount $currency via legacy system"; }}
// Nouvelle interface que nous voulons utiliserinterface NewPaymentInterface { public function pay(float $amount): string;}
// Adaptateurclass PaymentAdapter implements NewPayme