Styles

jeudi 3 septembre 2009

L'orienté objet : plus qu'un cache misère

Quels sont les caractéristiques principales d'un programme écrit par un néophyte ? des noms de variables incompréhensibles ? aucune organisation du code ? La pire, et malheureusement la plus fréquente, car inhérente à l'incompréhension de la notion d'abstraction, c'est l'utilisation généralisée de variables globales.

L'emploie de variables globales, faut-il le rappeler, est considéré comme une mauvaise pratique, du fait même de sa "non-localité" : une variable globale peut être modifiée de n'importe où (sans même parler de sa volatilité), et n'importe quelle partie d'un programme peut en être dépendante. Cela rend donc le programme inmaintenable à partir d'une certaine taille.

Vulgaire pédanterie d'un béotien en mathématique : l'emploi de variables globales et les dépendances qu'il instille entre toutes les parties d'un programme me fait penser visuellement à un pavage hyperbolique du disque de Poincaré. Il montre bien que toute chose est dépendante d'une autre et change de couleur aux croisements des autres dépendances.

L'orienté-objet force à l'abstraction mais n'empêche pas les variables globales de proliférer. Au delà d'éléments globaux d'une application, l'emploie de variables globales s'est immiscé subrepticement au cœur des classes d'objet, et le paradigme Orienté-Objet en a fait son beurre.

On pourrait même croire que, suite à la reconnaissance, par toute la communauté des programmeurs, de l'emploie de variables globales comme mauvaise pratique, des êtres mal intentionnés auraient inventés un paradigme leur permettant de programmer localement avec des variables globales, de restreindre, en fait, les variables globales à quelques fonctions.

L'orienté-objet n'est qu'une manière déguisée de programmer en utilisant des variables globales. Il pousse (mais n'oblige pas) à s'intéresser aux invariants de classe et d'objet, de savoir, en fait, gérer des variables globales pour qu'elles ne posent aucun problème lors de l'appel des méthodes.

Nombreux ont été les échecs quant à la préservation de l'intégrité des données d'une classe vis à vis de ses méthodes. Il est apparu, avec le temps, des principes de construction d'une classe, qui permettent de mettre de l'ordre dans la gestion de ces variables globales, locale à un objet ou à une classe d'objet. Ces principes ont été clairement exprimés par Robert C. Martin dans ses livres et sur le site Web de sa société Object Mentor.

Les principes de conception de classes orientée-objet sont regroupés au travers de la mnémonique SOLID, et permettent ainsi de surpasser la difficulté de maintenir des données globales dans un objet :
  • S : Single Responsability Principle (SRP) : There should never be more than one reason for a class to change.
  • O : Open-Closed Principle (OCP) : A module should be open for extension but closed for modification.
  • L : Liskov Principle (LSP) : Subclasses should be substitutable for their base classes
  • I : Interface Segregation Principle (ISP) : Many client specific interfaces are better than one general purpose interface
  • D : Dependency Inversion Principle (DIP) : Depend upon Abstractions. Do not depend upon concretions.
Robert C. Martin énonce aussi des principes d'architecture des modules (packages) très intéressants qui permettent de mieux gérer les dépendances des modules entre eux à fin de tenir la plus grande promesse de l'orienté objet : la réutilisabilité.
  • Release Reuse Equivalency Principle (REP)
  • Common Closure Principle (CCP)
  • Common Reuse Principle (CRP)
  • Acyclic Dependencies Principle (ADP)
  • Stable Dependencies Principle (SDP)
  • Stable Abstractions Principle (SAP)
Ces principes sont tout aussi importants que ceux relevant de la conception de classes, et des outils permettent de vérifier de façon automatique dans la plupart des cas, qu'on ne les enfreint pas. C'est le cas de JDepend dans le monde Java, NDepend pour le monde .NET, PHP Depend, Module::Dependency pour Perl...

C'est bien le genre de métrique qu'on a envi, en tant que chef de projet, de mettre dans les 'hooks' de subversion et de bloquer tout commit qui ne les satisferait pas. Quand on a la responsabilité d'un projet pour lequel on vous a affecté sans possibilité de discuter, des débutants, on croit toujours pouvoir être Big Brother et scruter le moindre faits et gestes des développeurs, en leur mettant par exemple, comme dans les sous-doués passe le bac, une bonne décharge électrique à chaque fois qu'ils essaient de commiter du code pas convenable.

Le problème c'est que tout ces principes ne sont pas toujours mis en œuvre dans les modules et librairies de base des langages comme Java notamment (par exemple, la fameuse classe Date qui au fur et à mesure des versions de java s'est vue refondre entièrement sans jamais atteindre une bonne implémentation, des fous sont même allez jusqu'à déposer un brevet logiciel pour refondre cette classe. La description du brevet est instructive sur les limites de la classe Date)

Ceci dit, une orientation objet bien maîtrisée peut aboutir aux nobles objectifs qu'elles s'était fixés dans la mesure où l'on sait que l'on joue avec le feu des variables globales.

Aucun commentaire: