Programmation

La définition du principe SOLID en PHP

Publié le · Mis à jour le 2 min de lecture

SOLID est un acronyme regroupant les cinq premiers principes majeurs de conception logicielle orientée objet (POO). Appliqués avec discernement, ils rendent le code plus facile à maintenir, plus lisible, plus flexible et plus robuste. Voici chacun d'eux, appliqué à PHP.

S — Responsabilité unique (SRP)

Une classe ne devrait avoir qu'une seule raison de changer. Une classe fourre-tout doit être scindée en classes plus petites et ciblées. Ici, une classe User qui gère à la fois le stockage, le courriel de bienvenue et les permissions est divisée en trois.

class User { public function __construct(public string $name, public string $email) {} }

class UserRepository { public function save(User $u): void { /* écrit en base de données */ } }
class WelcomeMailer  { public function send(User $u): void { /* envoie le courriel */ } }
class PermissionChecker { public function can(User $u, string $action): bool { /* ... */ } }

O — Ouvert/fermé (OCP)

Le code doit être ouvert à l'extension, fermé à la modification : on étend par l'héritage et les interfaces plutôt qu'en réécrivant l'existant. Une classe Database câblée pour MySQL devrait être modifiée pour accepter PostgreSQL. La solution : une interface commune et une implémentation par base de données.

interface Database { public function connect(): void; }

class MySQLDatabase      implements Database { public function connect(): void { /* ... */ } }
class PostgreSQLDatabase implements Database { public function connect(): void { /* ... */ } }

L — Substitution de Liskov (LSP)

Une sous-classe doit pouvoir remplacer sa classe parente sans changer le comportement du programme. Elle respecte donc les signatures, les types de retour et les exceptions du parent. L'exemple classique : un Square qui étend Rectangle. Modifier une seule dimension fausse alors le calcul de l'aire, et la substitution échoue.

I — Ségrégation des interfaces (ISP)

Plusieurs petites interfaces spécifiques valent mieux qu'une grosse interface générale : chaque classe n'implémente que les méthodes dont elle a besoin. Une interface DatabaseOperations trop touffue gagne à être découpée.

interface Readable { public function find(int $id): ?array; }
interface Writable { public function insert(array $row): int; }

class ReportDatabase implements Readable { /* lecture seule */ }
class AppDatabase    implements Readable, Writable { /* lecture et écriture */ }

D — Inversion des dépendances (DIP)

Les modules de haut niveau ne devraient pas dépendre des modules de bas niveau : les deux dépendent d'abstractions. On injecte donc une interface plutôt que d'instancier une classe concrète.

class OrderService {
    public function __construct(private Database $db) {} // dépend de l'abstraction
}

$service = new OrderService(new MySQLDatabase());

En résumé

SOLID n'est pas une religion, mais un ensemble de repères. Appliquez-le quand la complexité le justifie, et vous obtiendrez un code que vous aurez plaisir à relire dans six mois.

Lectures connexes : Les avantages de PHP et Les 10 meilleures façons d'apprendre à programmer en PHP.

À lire aussi