Développement

SOLID — Les 5 principes du design logiciel expliqués

SOLID — Les 5 principes du design logiciel expliqués

Les principes SOLID sont la base d'une architecture logicielle propre, maintenable et évolutive.

S — Single Responsibility Principle (SRP)

Une classe ne doit avoir qu'une seule raison de changer.

// ❌ Mauvais : la classe fait trop de choses
class ArticleManager {
    public function getFromDb(int $id) { /* ... */ }
    public function renderHtml(Article $article) { /* ... */ }
    public function save(Article $article) { /* ... */ }
}

// ✓ Bon : responsabilités séparées
class ArticleRepository {
    public function find(int $id) { /* ... */ }
    public function save(Article $article) { /* ... */ }
}
class ArticlePresenter {
    public function render(Article $article) { /* ... */ }
}

O — Open/Closed Principle (OCP)

Ouvert à l'extension, fermé à la modification.

Utilisez des interfaces et l'injection de dépendances.

// ❌ Mauvais : modifier la classe pour ajouter un export
class ReportExporter {
    public function export(array $data, string $format) {
        if ($format === 'pdf') { /* ... */ }
        if ($format === 'csv') { /* ... */ }
    }
}

// ✓ Bon : on peut ajouter des exportateurs sans toucher au code existant
interface ExporterInterface {
    public function export(array $data): string;
}
class PdfExporter implements ExporterInterface { /* ... */ }
class CsvExporter implements ExporterInterface { /* ... */ }

L — Liskov Substitution Principle (LSP)

Une instance d'un type doit pouvoir être remplacée par une instance d'un sous-type sans altérer le programme.

Si une classe enfant ne peut pas faire tout ce que sa classe parente fait, l'héritage est probablement mauvais.

// ❌ Mauvais : un carré n'est pas un rectangle (si mutable)
class Rectangle {
    public function setWidth(int $w) { $this->width = $w; }
    public function setHeight(int $h) { $this->height = $h; }
}
class Square extends Rectangle {
    public function setWidth(int $w) { $this->width = $w; $this->height = $w; }
    public function setHeight(int $h) { $this->width = $h; $this->height = $h; }
}
// $rect = new Square(); $rect->setWidth(5); $rect->setHeight(4);
// $rect->width != 5 -> violation du contrat

I — Interface Segregation Principle (ISP)

Ne forcez pas un client à implémenter une interface qu'il n'utilise pas.

Préférez de petites interfaces spécifiques à de grosses interfaces génériques.

// ❌ Mauvais : une classe qui ne peut que lire doit implémenter `write`
interface FileSystem {
    public function read(string $path): string;
    public function write(string $path, string $content): void;
}

// ✓ Bon : interfaces ségrégées
interface ReadableFileSystem {
    public function read(string $path): string;
}
interface WritableFileSystem {
    public function write(string $path, string $content): void;
}

D — Dependency Inversion Principle (DIP)

Les modules de haut niveau ne doivent pas dépendre des modules de bas niveau. Les deux doivent dépendre d'abstractions.

// ❌ Mauvais : le contrôleur dépend d'une implémentation concrète
class UserController {
    private $db;
    public function __construct() {
        $this->db = new MySqlConnection(); // Couplage fort
    }
}

// ✓ Bon : dépend d'une interface (abstraction)
class UserController {
    private $db;
    public function __construct(DatabaseConnectionInterface $db) {
        $this->db = $db;
    }
}

// Commentaires (0)

Connectez-vous pour laisser un commentaire.

Aucun commentaire pour le moment.