Principes SOLID en PHP : théorie et pratique
SOLID est un ensemble de cinq principes fondamentaux de la programmation orientée objet, formulés par Robert Martin. Ils aident à créer un code flexible, maintenable et évolutif. Dans cet article, nous allons détailler chaque principe avec des exemples en PHP, des concepts simples aux scénarios pratiques réels.
1. Single Responsibility Principle (SRP) — Principe de responsabilité unique
Énoncé : Une classe ne doit avoir qu'une seule raison de changer. En d'autres termes, chaque classe est responsable d'une seule tâche ou fonctionnalité.
La violation du SRP conduit souvent à des "objets divins" qui en savent et en font trop. Regardons un mauvais exemple :
class Report { public function generate($data) { // Génération du rapport return "Rapport : " . json_encode($data); }
public function saveToFile($filename, $content) { file_put_contents($filename, $content); }
public function sendEmail($to, $subject, $body) { mail($to, $subject, $body); }}Ici, la classe Report est responsable de la génération, de la sauvegarde et de l'envoi — trois responsabilités différentes. Corrigeons cela :
class ReportGenerator { public function generate($data) { return "Rapport : " . json_encode($data); }}
class FileSaver { public function save($filename, $content) { file_put_contents($filename, $content); }}
class EmailSender { public function send($to, $subject, $body) { mail($to, $subject, $body); }}
// Utilisation$report = new ReportGenerator();$content = $report->generate($data);
$saver = new FileSaver();$saver->save('report.txt', $content);
$sender = new EmailSender();$sender->send('admin@example.com', 'Rapport prêt', $content);Conseil pratique : Si vous voyez la conjonction "et" dans le nom d'une classe (par exemple, UserAndLogger), c'est un signe certain de violation du SRP.
2. Open-Closed Principle (OCP) — Principe d'ouverture/fermeture
Énoncé : Les classes doivent être ouvertes à l'extension, mais fermées à la modification. Vous devez pouvoir ajouter de nouvelles fonctionnalités sans modifier le code existant.
La violation de l'OCP se produit lorsque l'ajout d'un nouveau type nécessite de modifier les classes existantes. Exemple de mauvais code :
class PaymentProcessor { public function process($type, $amount) { if ($type === 'credit_card') { // Traitement de la carte de crédit } elseif ($type === 'paypal') { // Traitement PayPal } elseif ($type === 'crypto') { // Traitement de la cryptomonnaie } // Ajout d'un nouveau type = modification de cette classe }}La solution est d'utiliser le polymorphisme via des interfaces :
interface PaymentMethod { public function process($amount);}
class CreditCardPayment implements PaymentMethod { public function process($amount) { echo "Traitement de la carte de crédit pour un montant de $amount"; }}
class PayPalPayment implements PaymentMethod { public function process($amount) { echo "Traitement PayPal pour un montant de $amount"; }}
class PaymentProcessor { public function process(PaymentMethod $method, $amount) { $method->process($amount); }}
// Utilisation$processor = new PaymentProcessor();$processor->process(new CreditCardPayment(), 100);$processor->process(new PayPalPayment(), 200);Désormais, l'ajout d'un nouveau mode de paiement (par exemple, ApplePayPayment) ne nécessite pas de modifier PaymentProcessor.
3. Liskov Substitution Principle (LSP) — Principe de substitution de Liskov
Énoncé : Les objets des sous-classes doivent être interchangeables avec les objets de la classe de base