OpenClosed
🛠️ Pourquoi le OCP est-il important ?
| Avantage | Explication |
|---|---|
| Stabilité | Le code existant et testé n'est pas modifié, ce qui limite les bugs. |
| Extensibilité | Il est facile d'ajouter de nouvelles fonctionnalités. |
| Maintenabilité | Le code est plus facile à comprendre et à faire évoluer. |
⚡ Note : Le respect de l'OCP permet de construire un système robuste, évolutif et moins sujet aux erreurs lors des modifications.
🪄 Comment appliquer le OCP ?
Pour respecter l'OCP :
- Utiliser l'abstraction : interfaces, classes abstraites, ou contrats clairs.
- Privilégier la composition et l'héritage pour étendre le comportement sans modifier les classes existantes.
- Éviter les conditions (
if/else,switch) qui changent souvent, en déléguant la logique à des classes spécialisées.
ℹ️ Astuce : chaque fois que vous sentez que vous devez modifier du code existant pour ajouter une fonctionnalité, demandez-vous si une nouvelle classe ou interface peut résoudre le problème.
📩 Exemple en C#
❌ Mauvaise pratique : Code fermé à l'extension, ouvert à la modification
public class OrderProcessor
{
public void ProcessOrder(Order order)
{
if (order.Type == "Standard")
{
// Logique de traitement pour une commande standard
}
else if (order.Type == "Express")
{
// Logique de traitement pour une commande express
}
}
}
ℹ️ Problème : Ajouter un nouveau type de commande nécessite de modifier
OrderProcessor, ce qui viole l'OCP et risque de créer des régressions.
✅ Bonne pratique : Code ouvert à l'extension, fermé à la modification
public interface IOrderProcessor
{
void Process(Order order);
}
public class StandardOrderProcessor : IOrderProcessor
{
public void Process(Order order)
{
// Logique de traitement pour une commande standard
}
}
public class ExpressOrderProcessor : IOrderProcessor
{
public void Process(Order order)
{
// Logique de traitement pour une commande express
}
}
// Ajout d'un nouveau type de commande sans modifier le code existant
public class InternationalOrderProcessor : IOrderProcessor
{
public void Process(Order order)
{
// Logique de traitement pour une commande internationale
}
}
// Utilisation
public class OrderService
{
private readonly Dictionary<string, IOrderProcessor> _processors;
public OrderService()
{
_processors = new Dictionary<string, IOrderProcessor>
{
{ "Standard", new StandardOrderProcessor() },
{ "Express", new ExpressOrderProcessor() },
{ "International", new InternationalOrderProcessor() }
};
}
public void ProcessOrder(Order order)
{
_processors[order.Type].Process(order);
}
}
ℹ️ Avantages :
- Ajouter un nouveau type de commande : créer simplement une nouvelle classe implémentant
IOrderProcessor.- Le code existant (
OrderService) reste inchangé.- Le système est flexible, extensible et conforme à l'OCP.
⚡ Problèmes fréquents / Causes probables
| Symptôme | Cause probable | Solution |
|---|---|---|
| Ajout de nouvelles fonctionnalités entraîne des modifications fréquentes | Code fermé à l'extension | Introduire des interfaces et classes spécialisées |
Multiples conditions if/else dans la même méthode | Logique métier mal répartie | Utiliser le polymorphisme pour déléguer la logique à des classes dédiées |
| Difficulté à tester certaines fonctionnalités sans modifier le code existant | Couplage fort et manque d'abstraction | Appliquer OCP avec composition et interfaces |
🎯 Conclusion
Le Open/Closed Principle permet de concevoir des systèmes logiciels stables, évolutifs et faciles à maintenir. En utilisant l'abstraction et la composition, il est possible d'ajouter de nouvelles fonctionnalités sans risquer de casser le code existant, garantissant ainsi la qualité et la flexibilité du logiciel.