2008-12-17 7 views
26

Dans tous mes projets jusqu'à présent, j'utilise l'utilisation du modèle singleton pour accéder à la configuration de l'application dans toute l'application. Dernièrement je vois beaucoup d'articles prenant sur ne pas utiliser le modèle de singleton, parce que ce modèle ne favorise pas la testabilité aussi il cache la dépendance de Composant. Ma question est quelle est la meilleure façon de stocker la configuration de l'application, qui est facilement accessible dans toute l'application sans passer l'objet de configuration partout dans l'application?Singleton pour la configuration de l'application

Merci à l'avance

Madhu

Répondre

21

Je pense qu'une configuration d'application est une excellente utilisation du motif Singleton. J'ai tendance à l'utiliser moi-même pour éviter d'avoir à relire la configuration chaque fois que je veux y accéder et parce que j'aime que la configuration soit fortement typée (par exemple, ne pas avoir à convertir les valeurs non-string à chaque fois). Je construis généralement des méthodes backdoor pour mon Singleton afin de supporter la testabilité - c'est-à-dire la possibilité d'injecter une configuration XML pour pouvoir la définir dans mon test et la capacité de détruire le Singleton afin qu'il soit recréé quand nécessaire. Généralement, ce sont des méthodes privées auxquelles j'accède par réflexion afin qu'elles soient cachées de l'interface publique.

EDIT Nous vivons et apprenons. Bien que je pense que la configuration d'application est l'un des rares endroits où utiliser un Singleton, je ne le fais plus. Généralement, maintenant, je vais créer une interface et une implémentation de classe standard en utilisant des champs de support Lazy<T> statiques pour les propriétés de configuration. Cela me permet d'avoir le comportement "initialize once" pour chaque propriété avec une meilleure conception pour la testabilité.

+3

+1, les gens aiment créer DO leurs petites règles comme « une seule sortie d'une boucle » ou « non singletons permis ». Je préférerais être pragmatique plutôt que dogmatique puisque le dogme mène à ce que les gens ne puissent pas penser par eux-mêmes. Si vous ne pouvez avoir qu'un seul objet X, vous ne devriez avoir qu'un seul objet XConfig. – paxdiablo

+2

Avoir une seule instance d'un objet de configuration est bien et souhaitable, mais cela ne rend pas l'utilisation d'un Singleton pour l'obtenir.Utiliser des hacks comme des méthodes spécifiques à un test dans votre classe n'est pas bon non plus pour le code ou les tests. – ColinD

1

Pour cette situation spécifique, je voudrais créer un objet de configuration et le transmettre à ceux qui en ont besoin.

Comme c'est la configuration, il doit être utilisé uniquement dans certaines parties de l'application et ne doit pas nécessairement être omniprésent.

Cependant, si vous n'avez pas eu de problème à les utiliser et que vous ne voulez pas le tester aussi dur, vous devriez continuer comme vous l'avez fait jusqu'à aujourd'hui.

Lisez la discussion sur les raisons pour lesquelles ils sont considérés comme dangereux. Je pense que la plupart des problèmes surviennent lorsque beaucoup de ressources sont détenues par le singleton.

Pour la configuration de l'application, je pense qu'il serait prudent de le garder comme il est.

5

Utilisez l'injection de dépendances pour injecter l'objet de configuration unique dans toutes les classes qui en ont besoin. De cette façon, vous pouvez utiliser une configuration fictive pour tester ou tout ce que vous voulez ... vous n'êtes pas explicitement sortir et obtenir quelque chose qui doit être initialisé avec des fichiers de configuration. Avec l'injection de dépendance, vous ne passez pas l'objet non plus.

+0

Donc, dans ce cas, l'objet de configuration sera toujours un singleton, mais le code utilisera une interface, au lieu de directement la classe, et l'implémentation réelle sera injectée par Spring? Nous pourrions donc injecter un objet simulé pour le tester. Est-ce correct? – stivlo

+0

@stivlo: À droite, l'instance unique serait gérée par le conteneur d'injection de dépendances (que ce soit Spring, Guice ou autre) et le code pourrait utiliser une interface, vous permettant de transmettre une implémentation avec les paramètres que vous voulez essai. Il ne doit pas nécessairement être un simulacre ... il pourrait être l'implémentation réelle, juste avec les paramètres que vous ajoutez vous-même au lieu de lire à partir d'un fichier. – ColinD

+0

Donc, @ColinD, s'il vous plaît gardez avec moi, toute l'attention ici n'est pas que Singleton est mauvais pour lui-même, il pourrait être approprié, surtout pour la configuration de l'application ou peut-être pour maintenir un pool de connexions lorsque la dépendance est masquée, nous ne voyons pas les dépendances de code. Définir cette dépendance avec un conteneur d'injection de dépendances le rend explicite. Ce genre de conclusion est un peu différent du dogme "éviter les singletons", seriez-vous d'accord avec cela? – stivlo

0

Le motif singleton semble être le chemin à parcourir. Voici un Setting class que j'ai écrit qui fonctionne bien pour moi.