Double Possible:
Ce qui est si mal à propos de Singletons?Il est compréhensible que de nombreux modèles de conception peuvent dans certains cas être victimes de violence, et comme maman dit toujours: "Trop d'une bonne chose n'est pas toujours bon!"
J'ai remarqué que ces derniers jours, je suis en utilisant les Singletons beaucoup, et je suis inquiet que je pourrais abuser du modèle de conception de moi-même, et en cours d'exécution de plus en plus profondément dans une mauvaise pratique genre d'habitude.
Nous sommes en train de développer une application Flex qui dispose d'une assez grande hiérarchique structure de données conservées en mémoire pendant que l'utilisateur travaille sur elle. L'utilisateur peut charger, enregistrer, de modifier et d'actualiser les données sur la demande.
Ces données sont centralisées par le biais d'une classe Singleton, qui rassemble un couple de ArrayCollections, des Tableaux, des objets de valeur et quelques autres natif variables membres exposés par des getters et setters.
Pour obtenir une référence à nos données à partir de n'importe où dans l'application, nous ne l'ensemble du Modèle.méthode getInstance() type de chose, que je suis sûr que tout le monde est familier avec. Cela nous permet de toujours obtenir nos mains sur la même copie de données, car lorsque nous avons conçu, nous dit que c'est seulement une fois que l'instance est autorisé à exister au cours de la vie de l'application.
À partir de cette banque de données centrale, il est facile pour nous, par exemple, l'expédition de la propriété changé événements, et peut avoir plusieurs composants de l'INTERFACE utilisateur qui font référence à la centrale de données, mettre à jour leurs écrans afin de refléter les changements qui ont eu lieu.
Jusqu'à présent, cette approche a été efficace et s'est avéré très utile à nos circonstances.
Je suis la recherche cependant, que je suis un peu tend lors de la création de nouvelles classes. Des Questions comme si une classe d'être un Singleton, ou doit-il plutôt être géré d'une autre manière, comme peut-être à l'aide d'une usine par exemple, ont tendance à être parfois un peu difficile, avec un peu d'incertitude.
Où dois-je tracer la ligne avec des célibataires? Est-il une bonne ligne de conduite pour décider quand utiliser les Singletons et quand rester loin d'eux.
Aussi, quelqu'un peut-il me conseiller un bon livre sur les modèles de conception?
- Ce qui est si mal à propos de singletons? (5 réponses )
Réponses
Trop de publicités?Oui, les singletons sont des mauvais. Ils sont mauvais parce que tout ce qu'ils font pour vous est de combiner deux propriétés, chaque de ce qui est mauvais sur 95% du temps. (Ce qui signifie qu'en moyenne, les singletons sont des mauvais 99.75% du temps ;))
Un singleton, tel que défini par le GoF, est une structure de données qui:
- Les subventions globales de l'accès à un objet, et
- Applique qu'une seule instance de l'objet peut jamais exister.
Le premier est généralement considéré comme une mauvaise chose. Nous n'aimons pas les variables globales. La deuxième est un peu plus subtile, mais généralement, il n'y a pratiquement pas de cas où c'est une restriction raisonnable de les appliquer.
Parfois, il n'a de sens que pour avoir qu'une seule instance d'un objet. Dans ce cas, vous choisissez de ne créer qu'un seul. Vous n'avez pas besoin d'un singleton à la faire respecter.
Et généralement, même quand il "fait sens" pour avoir une seule instance, il s'avère ne pas faire de sens, après tout. Tôt ou tard, vous allez avoir besoin de plus d'un enregistreur. Ou plus d'une base de données. Ou vous allez avoir à recréer des ressources pour chacun de vos tests unitaires, ce qui signifie que nous devons être en mesure de créer à volonté. Il est prématurément la suppression de la flexibilité de notre code, avant de nous comprendre les conséquences.
Les Singletons cacher des dépendances et de l'augmentation de couplage (chaque classe peut potentiellement dépendent d'un singleton, ce qui signifie que la classe ne peut pas être réutilisés dans d'autres projets, sauf si nous avons également réutiliser tous nos singletons), et parce que ces dépendances ne sont pas immédiatement visibles (comme la fonction/paramètres du constructeur), nous n'avons pas les remarquer, et, généralement, ne pense pas à ce sujet lorsque nous les créer. C'est tellement facile de tirer juste dans un singleton, il agit presque comme une variable locale et tous, nous avons tendance à utiliser beaucoup une fois qu'ils sont là. Et qui les rend presque impossible d'enlever de nouveau. En fin de compte vous, peut-être pas avec code spaghetti, mais avec des spaghettis des graphes de dépendance. Et tôt ou tard, votre emballement dépendances signifie que les singletons commencer à en fonction les uns des autres, et puis, vous obtenez des dépendances circulaires lorsque l'on est tenté d'initialisation.
Ils font qu'il est extrêmement difficile de test unitaire. (Comment voulez-vous tester une fonction qui appelle des fonctions sur un objet singleton? Nous ne voulons pas le réel singleton code qui doit être exercé, mais comment pouvons-nous éviter cela?
Oui, les singletons sont des mauvais.
Parfois, vous voulez vraiment un mondial. Ensuite, utilisez un mondial, pas un singleton.
Parfois, le très très très rarement, vous pouvez avoir une situation où la création de plusieurs instances d'une classe est une erreur, et où il peut ne pas être fait sans provoquer des erreurs. (Sur le seul cas que je pense, et même qui est artificiel, c'est que si vous êtes représentant certains matériels. Vous n'avez qu'un GPU, donc, si vous allez à l'associer à un objet dans votre code, il serait logique qu'une seule instance peut exister). Mais si vous vous trouvez dans une telle situation (et encore, pour l'accent, d'une situation où de multiples instances de provoquer de graves erreurs, et pas seulement une situation où la "je ne connais pas de cas d'utilisation pour plus d'une instance"), puis de faire respecter cette contrainte, mais le faire sans aussi de rendre l'objet visible au niveau mondial.
Chacun de ces deux propriétés peuvent être utiles, dans de rares cas. Mais je ne peux pas penser à un seul cas où la combinaison d'entre eux serait une bonne chose.
Malheureusement, beaucoup de gens ont eu l'idée selon laquelle "les Singletons sont de la programmation orientée objet conforme globals." Non, ils ne le sont pas. Ils continuent de souffrir des mêmes problèmes que les variables globales, en plus de l'introduction de certains autres, complètement sans lien entre elles. Il n'y a absolument aucune raison de préférer un singleton sur une ancienne brut mondial.
L'essentiel à retenir est que les modèles de conception sont juste un outil pour vous aider à comprendre les concepts abstraits. Une fois que vous avez que de la compréhension, de la restriction de vous-même spécifiquement à une "recette" à partir d'un livre est inutile et nuit à votre capacité à écrire le code le plus approprié pour vos besoins.
Cela dit, en lisant des livres comme GoF vous présente plus la façon de penser des problèmes de sorte que lorsque vient le temps de mettre en place quelque chose sur votre propre, vous aurez un ensemble plus large de points de vue pour aborder le problème de.
Dans votre cas, si vous utilisez singleton a de sens que dans tous les cas, aller droit devant. Si elle "sorte de" s'inscrit et que vous avez à mettre en œuvre dans certains maladroit, alors vous avez besoin de trouver une nouvelle solution. En forçant un modèle qui n'est pas parfait, c'est un peu comme le martelage d'une cheville carrée dans un trou rond.
Étant donné que vous dites "cette approche a été efficace et s'est avéré très pratique pour notre situation," je pense que vous vous débrouillez bien.
Voici quelques bons livres:
"Bande des Quatre" Livre - le livre classique pour les modèles de conception
La tête la Première, les Modèles de Conception - j'ai entendu parler de ce recommandé par quelques personnes comme une alternative
Les développeurs de logiciels semblent être assez répartis en deux camps, selon qu'ils privilégient une idéaliste style de codage ou un pragmatique:
- Idéaliste: ne Jamais utiliser le pattern singleton.
- Pragmatique: Éviter le pattern singleton.
Personnellement, je préfère l'approche pragmatique. Parfois, il est logique de briser les règles, mais seulement si vous comprenez vraiment ce que vous faites et qui sont disposés à accepter les risques associés. Si vous pouvez répondre "oui" aux questions ci-dessous concernant votre cas d'utilisation spécifiques, le pattern singleton peut produire des avantages pratiques.
- Est le singleton externe à votre application? Bases de données, des files d'attente des services, et l'ESBs sont tous parfaitement valide exemples de macro d'un singleton.
- KISS: Est vous toute application limité à 2-3 interne singletons?
- SEC: ce Sont les singletons mondial par nature et entraînerait donc avoir à l'aplomb des références dans, presque tous les objets dans votre application? (par exemple, un enregistreur ou d'un composant médiateur)?
- Faites votre singletons ne dépendent les uns des autres, et/ou de l'environnement d'exploitation?
- Avez-vous veillé à la bonne démarrage et d'arrêt de séquences pour chaque singleton, y compris les considérations relatives à la gestion de la mémoire? Par exemple, un "Grand Central"de style pool de threads peut-être besoin d'avoir de l'instance Run() et d'Arrêt() méthodes dans main (), de sorte que les tâches sont garantis pour fonctionner uniquement lorsque les objets qu'ils opèrent sont dans un état valide.
Les Singletons ne tuent pas les programmes, les programmeurs de tuer des programmes.
Comme toute construction de programmation, lorsqu'il est utilisé de façon appropriée, vous ne serez pas se tirer dans le pied.
Les livres recommandés sont beaux, mais ils ne sont pas toujours donner assez de fond qui vient avec l'expérience, quand vous pourriez faire le choix d'utiliser un Singleton).
Cette expérience vient seulement quand vous avez trouvé Singleton est un mauvais choix lorsque vous avez besoin d'avoir plusieurs instances, et tout d'un coup, vous avez beaucoup de mal à injecter de l'objet de références partout.
Parfois c'est mieux d'aller de l'avant et avoir les références de l'objet en place, mais le fait que vous êtes à l'aide de Singleton à tous les aide à cerner l'étendue du problème que vous pourriez avoir si vous aviez à refactoriser le code pour un design différent. Je crois que c'est une très bonne chose: c'est à dire juste d'avoir une classe à tous (même si elles sont mal conçues) donne une certaine capacité à voir les effets d'un changement de la classe.
Nous avons commencé un projet où nous sommes confrontés à la même question, qui est, comment faire pour accéder au modèle, et en particulier son élément racine. Le projet n'est pas un Flex app, mais un jeu! web app, mais cela ne compte pas vraiment.
Avoir un seul objet unique dans le système est très bien, le problème est comment faire pour y accéder. Ainsi, le débat singleton est liée à la notion d' inversion de dépendance (DI), et comment obtenir des objets.
Les principaux arguments pour les DI sont les suivantes:
- la testabilité et se moquant de
- le découplage de l'instanciation des objets d'utilisation (ce qui peut mener à la gestion du cycle de vie)
- la séparation des préoccupations
Approches possibles pour les DI sont (voir le classique de l'article de Fowler):
- pour passer de l'objet autour des paramètres de la méthode
- service locator
- DI-cadre
Dans cette perspective, le pattern singleton est juste une sorte de service de localisation, par exemple, Model.getInstance()
.
Mais pour offrir un maximum de flexibilité face à des changements à venir, la référence à l'objet unique doit être passé autour autant que possible, et obtenu avec Model.getInstance()
seulement quand c'est nécessaire. Cela permettra également d'obtenir plus propre code.