Les principes SOLID sont des bonnes pratiques en programmation orientée objet qui permettent d'avoir un code plus modulaire, maintenable et extensible.
1️⃣ S - Principe de Responsabilité Unique (Single Responsibility Principle - SRP)
Une classe ne doit avoir qu'une seule raison de changer.
❌ Mauvais exemple (Violation du SRP)
Une classe qui gère les informations du salarié et le calcul de la paie :
class Employe { private String nom; private double salaire; public Employe(String nom, double salaire) { this.nom = nom; this.salaire = salaire; } public void genererFichePaie() { System.out.println("Fiche de paie générée pour " + nom); } }
✅ Bon exemple (Respect du SRP)
Séparer les responsabilités :
class Employe { private String nom; private double salaire; public Employe(String nom, double salaire) { this.nom = nom; this.salaire = salaire; } } class PaieService { public void genererFichePaie(Employe employe) { System.out.println("Fiche de paie générée pour " + employe.getNom()); } }
2️⃣ O - Principe Ouvert/Fermé (Open/Closed Principle - OCP)
Une classe doit être ouverte à l'extension mais fermée à la modification.
❌ Mauvais exemple
Ajouter une nouvelle réduction oblige à modifier le code existant :
class Facture { public double calculerRemise(double montant, String typeClient) { if (typeClient.equals("VIP")) { return montant * 0.9; } else if (typeClient.equals("Fidèle")) { return montant * 0.95; } return montant; } }
✅ Bon exemple (Respect de l’OCP)
Utilisation du polymorphisme :
interface Remise { double appliquerRemise(double montant); } class RemiseVIP implements Remise { public double appliquerRemise(double montant) { return montant * 0.9; } } class Facture { public double appliquerRemise(double montant, Remise remise) { return remise.appliquerRemise(montant); } }
3️⃣ L - Principe de Substitution de Liskov (Liskov Substitution Principle - LSP)
Une classe dérivée doit pouvoir remplacer sa classe mère sans effet indésirable.
❌ Mauvais exemple
Un carré est un rectangle qui a ses quatre côtés de même longueur.
Mais, un carré ne peut pas toujours remplacer un rectangle : un carré a un coté et un rectangle a une longueur et une largeur
class Rectangle { protected int largeur, longueur; public void setLargeur(int largeur) { this.largeur = largeur; } public void setLongueur(int longueur) { this.hauteur = longueur; } } class Carre extends Rectangle { @Override public void setLargeur(int largeur) { this.largeur = this.longueur = largeur; } }
✅ Bon exemple
Utiliser des classes distinctes :
interface Forme { int getAire(); } class Rectangle implements Forme { private int largeur, longueur; public int getAire() { return largeur * longueur; } } class Carre implements Forme { private int cote; public int getAire() { return cote * cote; } }
4️⃣ I - Principe de Ségrégation des Interfaces (Interface Segregation Principle - ISP)
Une classe ne doit pas être forcée à implémenter des méthodes inutiles.
❌ Mauvais exemple
Une interface trop large :
interface Oiseau { void voler(); void nager(); } class Pingouin implements Oiseau { public void voler() { throw new UnsupportedOperationException(); } public void nager() { System.out.println("Le pingouin nage"); } }
✅ Bon exemple
Créer plusieurs interfaces :
interface OiseauVolant { void voler(); } interface OiseauMarin { void nager(); } class Aigle implements OiseauVolant { public void voler() { System.out.println("L'aigle vole"); } } class Pingouin implements OiseauMarin { public void nager() { System.out.println("Le pingouin nage"); } }
5️⃣ D - Principe d'Inversion des Dépendances (Dependency Inversion Principle - DIP)
Une classe doit dépendre d’abstractions et non d’implémentations concrètes.
❌ Mauvais exemple
Dépendance directe à une implémentation :
class MySQLDatabase { public void sauvegarderCommande(String commande) { System.out.println("Commande enregistrée en MySQL"); } } class ServiceCommande { private MySQLDatabase db = new MySQLDatabase(); public void traiterCommande(String commande) { db.sauvegarderCommande(commande); } }
✅ Bon exemple
Utiliser une interface pour découpler :
interface BaseDeDonnees { void sauvegarderCommande(String commande); } class MySQLDatabase implements BaseDeDonnees { public void sauvegarderCommande(String commande) { System.out.println("Commande enregistrée en MySQL"); } } class ServiceCommande { private BaseDeDonnees db; public ServiceCommande(BaseDeDonnees db) { this.db = db; } public void traiterCommande(String commande) { db.sauvegarderCommande(commande); } }
🎯 Conclusion
Les principes SOLID en Java permettent d’avoir un code modulaire, maintenable et extensible. Respecter ces bonnes pratiques améliore la qualité du code et évite les problèmes à long terme ! 🚀
Top comments (0)