Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Fathi Bellahcene

.Net m'a tuer!

OCP: Open-Closed Principle

Ce post fait partie d’une serie se proposant de présenter les principes SOLID. Vous  trouverez l’introducton ainsi que les liens vers les autres articles ici .

Définition

“les entités logicielles telles que les classes et les méthodes doivent être ouvertes pour l'extension, mais fermées à la modification.” (Bertrand Meyer)

C’est-à-dire que leur comportement peut être étendu ou bien complètement modifié si elles doivent remplir de nouveaux besoins (ouverte à l’extension) tout en s’assurant que leur code source ne peut pas être directement modifié, aucune modification n’est autorisée (fermé à la modification).

Comment l’appliquer

Après avoir lu cette définition, vous devez vous dire que cela semble contradictoire ! Comment une classe ou une méthode peut être à la fois ouverte pour extension et fermée à la modification ?!

Cela signifie simplement qu’une application doit être structurée de manière à pouvoir ajouter des fonctionnalités en touchant au minimum au code existant. A chaque modification de code, la possibilité de rajouter des bugs existe. Des impacts imprévus peuvent survenir amenant à la modification du comportement de la classe et donc de l’application. L’implémentation devient fragile, difficilement maintenable et sujette aux régressions.

Le principe OCP est également à l’origine de plusieurs bonnes pratiques de développement  Objet comme par exemple:

  • Les membres (field) d’une classe doivent toutes être privés et non pas public ou encore protected: Lorsque les membres d’une classe changent, chaque fonction qui dépend de ces membres doivent être modifiées. Donc, aucune fonction qui dépend d'un membre public ou protected ne peut être fermé par rapport à ce membre.
  • Pas de variables global: même cas que précédement, chaques méthode qui va dépendre d’une variable global ne sera pas fermé par rapport à cette variable.
  • Pas d’opération sur les types: cela entraine tres souvent l’impossibilité de fermer une méthode…on le verra dans l’exemple suivant et dans ce cas, il existe certains patterns qui nous assurent un respect du principe

Privilégier ces patterns, c’est éviter les violations du principe OCP!

Exemple!

Passons a un exemple afin de mieux cerner le problème: prenons le cas d’une classe qui écris des messages de Log en base de donnée ou sur un fichier.

image

   1: public class Logger
   2:  {
   3:      
   4:      private TypeLog _typelog;
   5:  
   6:      public  Logger(TypeLog typelog)
   7:      {
   8:          _typelog=typelog;
   9:      }
  10:  
  11:      public void WriteLog(string message)
  12:      {
  13:          switch (_typelog)
  14:          {
  15:              case TypeLog.File:
  16:                  WriteInFile(message);
  17:                  break;
  18:              case TypeLog.DataBase:
  19:                  WriteInDataBase(message);
  20:                  break;
  21:              default:
  22:                  break;
  23:          }
  24:      }
  25:  
  26:      private void WriteInFile(string message)
  27:      {//Do stuff
  28:      }
  29:  
  30:      private void WriteInDataBase(string message)
  31:      {//Do stuff
  32:      }
  33:   
  34:  }
  35:  
  36:  public enum TypeLog
  37:  { 
  38:      File,
  39:      DataBase
  40:  }
  41:  
  42:  

 

Le problème étant que si je dois en plus prendre en compte l’écriture via un service distant…on est obligé d’ajouter une valeur à l’énum et de modifier la classe Logger (ajout de la méthode + prise en compte). Bref on viole OCP deux fois.

La solution passe par l’implémentation du pattern Stratey (et un peu d’IoC au passage) comme il suit:

image

On ne dépend plus que de l’interface ILogger et on injecte dans le constructeur l’objet qui est en charge d’effectuer ce travail. Si on souhaite ajouter une nouvelle stratégie d’écriture de log, on a juste a implémenter l’interface ILogger et ca roule Sourire

La classe logger devient:

   1: public class Logger
   2:     {
   3:         
   4:         public ILogger _logger;
   5:  
   6:         public Logger(ILogger logger)
   7:         {
   8:             _logger= logger;
   9:         }
  10:  
  11:         public void WriteLog(string message)
  12:         {
  13:             _logger.WriteLog(message);
  14:         }
  15:  
  16:     }

On a l’interface ILogger:

 

   1: public interface ILogger
   2:   {
   3:       void WriteLog(string message);
   4:   }

ET les loggers:

   1: public class FileLogger : ILogger
   2:     {
   3:  
   4:         public void WriteLog(string message)
   5:         {
   6:             //do stuff
   7:         }
   8:     }
   9:  
  10:     public class ServiceLogger : ILogger
  11:     {
  12:  
  13:         public void WriteLog(string message)
  14:         {
  15:             //do stuff
  16:         }
  17:     }
  18:  
  19:  
  20:     public class DataBaseLogger : ILogger
  21:     {
  22:  
  23:         public void WriteLog(string message)
  24:         {
  25:             //do stuff
  26:         }
  27:     }

 

Dans cette exemple, on n’aborde pas la manière de choisir le “bon” logger, on pourrais imaginer dans ce cas une “Abstract Factory” qui aurait donc la charge de cette responsabilité.

Vous trouverez les sources des exemples ici:http://solidincsharp.codeplex.com/

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :
Posted: dimanche 4 décembre 2011 13:42 par fathi

Commentaires

Pas de commentaires

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01