Principes SOLID en Java : théorie et pratique pour un code propre

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : pourquoi SOLID est important pour un développeur Java



Dans le monde de la programmation orientée objet, la maintenance et l'extension du code deviennent de plus en plus complexes avec le temps. Sans une architecture claire, même un petit projet se transforme en "gros tas de boue", où la modification d'une fonction en casse dix autres. C'est là que les principes SOLID viennent à la rescousse — cinq règles fondamentales de conception de classes, formulées par Robert Martin (Oncle Bob).



Pour un développeur Java, SOLID n'est pas simplement une théorie, mais un outil pratique. Java, en tant que langage fortement typé avec un puissant système d'interfaces et d'héritage, est idéal pour implémenter ces principes. Dans cet article, nous allons décortiquer chaque principe du point de vue théorique et montrer des exemples de code Java concrets que vous pouvez appliquer immédiatement dans un projet.



1. Single Responsibility Principle (Principe de responsabilité unique)



Théorie

SRP stipule : une classe ne doit avoir qu'une seule raison de changer. Autrement dit, une classe doit être responsable d'une fonctionnalité unique et clairement définie. Si une classe en fait trop, elle devient difficile à tester, à modifier et à réutiliser.



Pratique en Java

Considérons une violation typique du SRP — une classe qui gère à la fois les données utilisateur et envoie des notifications :



// ❌ Violation du SRPpublic class User {    private String name;    private String email;

public void saveToDatabase() { // Sauvegarde en BDD }

public void sendWelcomeEmail() { // Envoi d'email }}


La bonne solution est de séparer les responsabilités en deux classes :



// ✅ Respect du SRPpublic class User {    private String name;    private String email;    // Getters et Setters}

public class UserRepository { public void save(User user) { // Sauvegarde en BDD }}

public class EmailService { public void sendWelcomeEmail(User user) { // Envoi d'email }}


Conclusion : chaque classe a désormais une seule raison de changer. User change uniquement si la structure des données change, UserRepository change si la logique BDD change, EmailService change si les modèles d'emails changent.



2. Open-Closed Principle (Principe d'ouverture/fermeture)



Théorie

OCP affirme : les classes doivent être ouvertes à l'extension, mais fermées à la modification. Cela signifie que les nouvelles fonctionnalités doivent être ajoutées via l'héritage ou la composition, sans toucher au code déjà testé.



Pratique en Java

Imaginez que vous ayez un calculateur de remises pour différents types de clients :



// ❌ Violation de l'OCPpublic class DiscountCalculator {    public double calculateDiscount(String customerType, double amount) {        if (customerType.equals(\"Regular\")) {            return amount * 0.1;        } else if (customerType.equals(\"Premium\")) {            return amount * 0.2;        }        return 0;    }}


Lors de l'ajout d'un nouveau type de client (par exemple, "Gold"), il faudrait modifier la classe existante. La solution est d'utiliser le polymorphisme :



// ✅ Respect de l'OCPpublic interface DiscountStrategy {    double calculate(double amount);}

public class RegularDiscount implements DiscountStrategy { @Override public double calculate(double amount) { return amount * 0.1; }}

public class PremiumDiscount implements DiscountStrategy { @Override public double calculate(double amount) { return amount * 0.2; }}

public class DiscountCalculator { private DiscountStrategy strategy;

public DiscountCalculator(DiscountStrategy strategy) { this.strategy = strategy; }

public double calculate(double amount) {

Blogs

Book Recommendations