jeudi 10 mars 2011

Principe ouvert/fermé

En programmation orientée objet, le principe ouvert/fermé signifie qu'une entité logicielle (classes, modules, fonctions, etc) devrait être ouverte pour extension, mais fermée pour modification. L'idée est que l'on puisse modifier le comportement d'une entité, sans en changer le code source.

Ce principe est particulièrement bien adapté à des environnements de production critiques, où tout changement du code source doit être approuvé par un processus jalonné par des revues de code, des tests unitaires, une phase de qualification, ... En effet, si modifier le code existant implique de détecter d'éventuelles régressions par une batterie de contrôles portant à la fois sur les anciennes et les nouvelles fonctionnalités, au contraire l'étendre peut réduire considérablement l'effort de qualification, puisque ce dernier ne portera que sur les nouveautés.

Depuis son apparition en 1988 dans l'ouvrage Object Oriented Software Construction, l'application de ce principe a largement évolué, et gagné en souplesse.

Principe ouvert/fermé selon Meyer :
On attribue généralement ce concept à Bertrand Meyer, l'auteur de Object Oriented Software Construction :
  • L'implémentation d'une classe en production ne doit pas être modifiée, sauf correction d'anomalies.
  • Ajouter ou changer une fonctionnalité implique de créer une nouvelle classe.
  • La nouvelle classe peut réutiliser le code de la classe existante, par héritage.
  • On est libre d'exposer la nouvelle implémentation par une nouvelle interface ou par l'interface existante.
D'après le principe de Meyer, une implémentation existante peut être réutilisée par héritage, alors que 2 interfaces ne devraient pas hériter l'une de l'autre.

Principe ouvert/fermé par polymorphisme :
Puis, entre 1996 et 2001, plusieurs personnes contribuent à redéfinir le principe ouvert/fermé en tirant profit de l'abstraction et du polymorphisme des langages objet :
  • Le comportement d'une entité peut reposer sur de multiples implémentations différentes.
  • Les implémentations adoptent toutes la même interface, ou héritent de la même classe de base abstraite.
  • L'interface (ou classe abstraite) existante ne peut pas être modifiée.
  • Ajouter ou changer une fonctionnalité implique de créer une nouvelle interface (ou classe abstraite).
  • Les implémentations peuvent être modifiées.
  • Les implémentations peuvent se substituer les unes aux autres par polymorphisme.
D'après le principe par polymorphisme, une interface (ou classe abstraite) existante peut être réutilisée par héritage, alors que 2 implémentations ne devraient pas hériter l'une de l'autre.

Synthèse et comparaison :

OCP selon MeyerOCP par Polymorphisme
Extension par héritage dela classe d'implémentationl'interface existante
Constantes entre 2 évolutionsimplémentation et interfaceinterface seulement
Modification possible pour-implémentations

On constate donc que le principe ouvert/fermé a évolué vers un niveau d'abstraction plus important, ainsi qu'une plus grande flexibilité. Une bonne illustration de ce principe est le design pattern Visiteur de la Guilde des Quatre.

Références :

Aucun commentaire: