2009-10-26 3 views

Répondre

13

Répondu à une question similaire il y a quelques jours here, mocking a Singleton. Le message original est pour C# .Net en ce qui concerne le comportement d'un singleton, mais devrait toujours s'appliquer. En ce qui concerne le modèle singleton, il n'y a rien de mal en soi - dans de nombreux cas, nous voulons centraliser la logique et les données. Cependant, il y a une très grande différence entre un singleton et une classe statique. Construire votre singleton en tant que classe statique, les codes durs que la mise en œuvre à chaque consommateur dans votre application - ce qui rend les tests unitaires très difficile!

Ce que vous voulez faire est de définir une interface pour votre singleton, en exposant les méthodes à utiliser par vos consommateurs. Vos clients à leur tour sont passé une référence à une classe d'implémentation par qui les instancie [en général c'est votre application, ou un conteneur si vous êtes familier avec l'injection de dépendance \ inversion de contrôle].

C'est ce framework, qui instancie les consommateurs, qui est chargé de s'assurer qu'une seule et unique instance flotte. Ce n'est vraiment pas un grand saut de la classe statique à la référence d'interface [comme démontré dans le lien ci-dessus], vous perdez simplement la commodité d'une instance globalement accessible - je sais, les références mondiales sont terriblement séduisantes, mais Luke a tourné le dos Dark Side, vous aussi!

De manière générale, les meilleures pratiques suggèrent d'éviter les références statiques, et encourage la programmation par rapport aux interfaces. Rappelez-vous, il est toujours possible d'appliquer le modèle singleton avec ces contraintes. Suivez ces directives, et vous ne devriez avoir aucun problème de test de votre unité de travail :)

Espérons que cela aide!


singleton! = Public static class, plutôt singleton == instance unique

1

I'm using the following pattern quand j'écris un singletons base statique que je peux simuler. Le code est Java, mais je pense que vous aurez une idée. Le principal problème de cette approche est que vous devez relâcher le constructeur pour protéger le paquet (ce qui détruit un vrai singleton). Comme une note de côté - le code va à la capacité de se moquer de votre code « statique » pas nécessairement appeler simplement

3

Le manque de testabilité est l'une des faiblesses majeures du modèle Singleton classique (méthode de classe statique retour une instance). En ce qui me concerne, c'est une justification suffisante pour re-concevoir un code qui utilise Singletons pour utiliser un autre design.

Si vous avez absolument besoin d'une instance singulière, alors l'injection de dépendances et l'écriture sur une interface, comme suggéré par johnny g, est définitivement la solution.

0

Si vous devez utiliser un singleton (et il y a des raisons de le faire ... mais j'essaierais toujours de l'éviter si possible). Je recommanderais d'utiliser un conteneur IOC pour le gérer. Je ne suis pas sûr s'il y en a un pour Delphi ou pas. Mais en Java, vous pouvez utiliser Spring, en. NET, vous pouvez utiliser Windsor/Castle. Un conteneur IOC peut contenir le Singleton et enregistrer différentes implémentations pour les tests.

Il est probablement trop grand d'un sujet pour entrer ici au-delà de cet extrait.

1

En général, j'utilise uniquement des singletons pour les objets de poids mouche ou des objets de valeur similaire. Regarder dans un conteneur IoC (comme discuté ci-dessus) est probablement une meilleure façon de gérer un objet partagé qu'un singleton.

Tenir compte que, dans Smalltalk (où beaucoup de ces modèles origine), vrai et faux étaient tous deux des singletons :)

+0

... en ce qui concerne Smalltalk: oui, mais vrai et faux sont _so_ testable :) – mjn

Questions connexes