Overblog
Editer l'article Suivre ce blog Administration + Créer mon blog
Laurent COCAULT

Le singleton est-il un anti-patron ?

Le singleton est-il un anti-patron ?

Il suffit en général d'avoir travaillé deux ou trois dans le développement logiciel pour qu'une évocation des « Design Patterns » du « Gang Of Four » vous renvoie à une expérience personnelle. C’est plutôt rassurant puisque cela signifie que ces patrons de conception ont trouvé leur place dans la plupart des développements logiciels. Mais lorsque je discute avec de jeunes développeurs, le patron qui est le plus souvent évoqué de manière spontanée est celui du Singleton. Or les développeurs qui ont un peu plus d’expérience affichent une certaine méfiance vis-à-vis de ce patron quand ils ne le considèrent pas carrément comme un anti-pattern.

L’argument qui est souvent affiché par ceux qui mettent en garde sur l’utilisation du patron de conception est celui de la testabilité. En effet, l’inconvénient du singleton est que ses implémentations de référence ne permettent généralement pas de surcharger son implémentation. Il n’est donc pas possible d’en proposer une doublure de test, ce qui contraint l’ensemble des tests qui en dépendent à utiliser l’implémentation opérationnelle, avec tous les inconvénients que cette implémentation peut tirer dans un environnement de test. Cet argument, que j’utilise personnellement, peut pourtant être contredit ; c’est ce que faisait l’oncle Bob dans un article datant de juillet 2015.

L’oncle Bob invite néanmoins en conclusion à limiter l’utilisation du singleton aux cas de figure où on souhaite garantir l’unicité d’une instance de classe dans une API publique. En définitive c’est bien ce à quoi est destiné le singleton ; le nom même du patron met en avant le besoin d’unicité auquel il répond. Ce rappel pourrait sembler superflu tant il semble évident ; pourtant j’ai souvent vu ce patron dévoyé. L’accès statique à l’instance unique du singleton présente un caractère « pratique » qui séduit de nombreux développeurs. Il est en effet possible d’accéder à cette instance depuis n’importe quelle partie du logiciel, sans qu’il soit nécessaire de la transmettre via des arguments d’appel.

Mais une telle utilisation présente deux inconvénients majeurs :

  • D’une part, elle ne permet pas de maitriser le contexte d’exécution d’une fonction puisque chaque fonction est susceptible d’utiliser le singleton en complément de ses arguments explicites. En plus d’un nouveau défaut de testabilité, il s’agit d’un problème de lisibilité des interfaces des fonctions, en particulier lorsqu’il s’agit d’opérations d’une API publique.
  • D’autre part, ce côté « pratique » favorise l’ajout de fonctions au singleton. Plutôt que de créer un autre singleton ou, mieux, de transmettre des services supplémentaires via les paramètres des opérations, les développeurs sont tentés d’ajouter de nouvelles méthodes au singleton existant qui devient au fur et à mesure un point focal pour l’ensemble des services et fonctions de l’application. Le singleton se transforme alors en objet dieu.

C’est donc bien plus par les risques de dérive auxquels il expose que le singleton est un patron à considérer avec méfiance, que par le problème de testabilité que je suis pourtant le premier à mettre en avant. Dans tous, les cas, il ne faut jamais oublier qu’un patron de conception n’est pas seulement un nom et une solution, mais aussi l’exposé de conditions d’applications et un ensemble de conséquences.

Partager cet article
Repost0
Pour être informé des derniers articles, inscrivez vous :
Commenter cet article