Nous avons une classe qui contient les informations de configuration de l'application. C'était un singleton. Après un examen architectural, on nous a dit de supprimer le singleton. Nous avons vu certains avantages de ne pas utiliser singleton dans les tests unitaires car nous pouvons tester différentes configurations en même temps.
Sans singleton, nous devons passer l'instance partout dans notre code. Cela devient tellement compliqué que nous avons écrit un wrapper singleton. Maintenant que nous portons le même code vers PHP et .NET, je me demande s'il existe un meilleur modèle que nous pouvons utiliser pour l'objet de configuration.
la source
La meilleure façon est d'utiliser un modèle Factory à la place. Lorsque vous construisez une nouvelle instance de votre classe (en usine), vous pouvez insérer les données `` globales '' dans l'objet nouvellement construit, soit en tant que référence à une seule instance (que vous stockez dans la classe de fabrique), soit en copiant les données dans le nouvel objet.
Tous vos objets contiendront alors les données qui vivaient dans le singleton. Je ne pense pas qu'il y ait beaucoup de différence dans l'ensemble, mais cela peut rendre votre code plus facile à lire.
la source
Je pourrais dire l'évidence ici, mais y a-t-il une raison pour laquelle vous ne pouvez pas utiliser un framework d'injection de dépendances tel que Spring ou Guice ? (Je crois que Spring est également disponible pour .NET maintenant).
De cette façon, le framework peut contenir une seule copie des objets de configuration, et vos beans (services, DAO, etc.) n'ont pas à se soucier de la recherche.
C'est l'approche que j'adopte habituellement!
la source
Si vous utilisez Spring Framework , vous pouvez simplement créer un bean normal. Par défaut (ou si vous définissez explicitement
scope="singleton"
) une seule instance du bean est créée et cette instance est renvoyée chaque fois que le bean est utilisé dans une dépendance ou récupéré viagetBean()
.Vous bénéficiez de l'avantage de l'instance unique, sans le couplage du modèle Singleton.
la source
L'alternative est de transmettre ce dont vous avez besoin au lieu de demander des choses à un objet.
la source
n'accumulez pas de responsabilités sur un seul objet de configuration car il se terminera par un très gros objet à la fois difficile à comprendre et fragile.
Par exemple, si vous avez besoin d'un autre paramètre pour une classe particulière, vous modifiez l'
Configuration
objet, puis recompilez toutes les classes qui l'utilisent. C'est quelque peu problématique.Essayez de refactoriser votre code pour éviter un objet commun, global et volumineux
Configuration
. Transmettez uniquement les paramètres requis aux classes clientes:devrait être remanié pour:
un framework d'injection de dépendances aidera beaucoup ici, mais ce n'est pas strictement nécessaire.
la source
Vous pouvez accomplir le même comportement de singleton en utilisant des méthodes statiques. Steve Yegge l'explique très bien dans ce post.
la source
Une classe contenant uniquement des méthodes et des champs statiques est-elle possible? Je ne sais pas exactement quelle est votre situation, mais cela vaut peut-être la peine de l'examiner.
la source
Dépend de quels outils / frameworks etc. sont utilisés. Avec les outils d'injection de dépendances / ioc, on peut souvent encore obtenir des performances / optimisations de singleton en demandant au conteneur di / ioc d'utiliser le comportement de singleton pour la classe requise - (comme une interface IConfigSettings) en ne créant qu'une seule instance de la classe. Cela pourrait encore être remplacé par des tests
Vous pouvez également utiliser une fabrique pour créer la classe et renvoyer la même instance à chaque fois que vous la demandez - mais pour le tester, elle peut renvoyer une version stubbed / simulée
la source
Examinez la possibilité de faire la configuration comme interface de rappel. Ainsi, votre code sensible à la configuration ressemblera à:
Le code d'initialisation du système ressemblera à:
la source
Vous pouvez utiliser un framework d'injection de dépendances pour soulager la douleur de transmettre l'objet de configuration. Une solution décente est ninject qui a l'avantage d'utiliser du code plutôt que xml.
la source
Peut-être pas très propre non plus, mais vous pourriez peut-être passer les bits d'information que vous souhaitez modifier à la méthode qui crée le singleton - au lieu d'utiliser
vous pouvez appeler
createSingleton(Information info)
directement au démarrage de l'application (et dans les méthodes setUp des tests unitaires).la source
Les singletons ne sont pas mauvais mais le modèle de conception est imparfait. J'ai une classe dont je souhaite créer une seule instance pendant l'exécution, mais que je souhaite créer plusieurs instances isolées pendant les tests unitaires pour garantir des résultats déterministes.
DI utilisant Spring, etc., est une très bonne option mais pas la seule.
la source