SOLID - Principes de conception orientée objet
Ensemble de cinq principes de conception qui rendent les logiciels orientés objet plus maintenables, flexibles et évolutifs.
Mis à jour le 10 janvier 2026
SOLID est un acronyme mnémotechnique regroupant cinq principes fondamentaux de la programmation orientée objet, popularisés par Robert C. Martin (Uncle Bob). Ces principes guident la conception de code propre, modulaire et résistant aux changements. Appliqués correctement, ils réduisent la dette technique et facilitent les évolutions futures.
Les cinq principes SOLID
- **S**ingle Responsibility Principle (SRP) : Une classe ne doit avoir qu'une seule raison de changer
- **O**pen/Closed Principle (OCP) : Ouvert à l'extension, fermé à la modification
- **L**iskov Substitution Principle (LSP) : Les sous-types doivent être substituables à leurs types de base
- **I**nterface Segregation Principle (ISP) : Préférer plusieurs interfaces spécifiques à une interface générale
- **D**ependency Inversion Principle (DIP) : Dépendre des abstractions, non des implémentations concrètes
Avantages de l'application SOLID
- Amélioration significative de la maintenabilité et de la lisibilité du code
- Réduction du couplage entre composants, facilitant les tests unitaires
- Facilitation du refactoring et de l'ajout de nouvelles fonctionnalités
- Diminution des bugs liés aux effets de bord lors de modifications
- Meilleure scalabilité architecturale pour accompagner la croissance du projet
Exemple concret : Violation puis application de SRP
// ❌ Violation du SRP : classe avec multiples responsabilités
class UserService {
createUser(data: UserData) {
// Validation
if (!data.email.includes('@')) {
throw new Error('Invalid email');
}
// Persistance
database.save(data);
// Notification
emailService.send(data.email, 'Welcome!');
// Logging
logger.log(`User ${data.email} created`);
}
}// ✅ Application du SRP : séparation des responsabilités
class UserValidator {
validate(data: UserData): boolean {
return data.email.includes('@');
}
}
class UserRepository {
save(user: User): void {
database.save(user);
}
}
class UserNotifier {
notifyCreation(email: string): void {
emailService.send(email, 'Welcome!');
}
}
class UserService {
constructor(
private validator: UserValidator,
private repository: UserRepository,
private notifier: UserNotifier
) {}
createUser(data: UserData): void {
if (!this.validator.validate(data)) {
throw new Error('Invalid user data');
}
const user = new User(data);
this.repository.save(user);
this.notifier.notifyCreation(user.email);
}
}Mise en œuvre progressive
- Commencer par le Single Responsibility Principle lors de nouveaux développements
- Identifier les points de variation et appliquer Open/Closed pour les anticiper
- Utiliser l'injection de dépendances pour respecter le Dependency Inversion Principle
- Réviser les hiérarchies d'héritage pour garantir la Liskov Substitution
- Décomposer les interfaces volumineuses selon Interface Segregation
- Intégrer les principes SOLID dans les code reviews et les standards d'équipe
Conseil pratique
N'appliquez pas SOLID de manière dogmatique. Commencez par SRP et DIP qui apportent le plus de valeur immédiate. Les autres principes s'appliquent naturellement lorsque le code évolue. Privilégiez la simplicité : un code simple qui fonctionne vaut mieux qu'une architecture sur-ingéniérée.
Outils et pratiques associés
- Frameworks d'injection de dépendances (InversifyJS, TSyringe, NestJS)
- Analyseurs statiques pour détecter les violations (SonarQube, ESLint avec règles architecturales)
- Outils de refactoring automatisé (IntelliJ IDEA, VS Code Refactoring tools)
- Diagrammes UML pour visualiser les dépendances et les abstractions
- Tests unitaires et mocks pour valider l'isolation des responsabilités
Les principes SOLID constituent un investissement à long terme qui transforme la capacité d'une équipe à livrer rapidement de nouvelles fonctionnalités. En réduisant la complexité accidentelle et en favorisant une architecture claire, ils permettent de maintenir une vélocité élevée même sur des projets matures. Leur maîtrise différencie les développeurs seniors capables d'anticiper l'évolution du code.
