Je recherche différentes façons de garantir que chaque instance d'une classe donnée est une instance identifiable de manière unique.
Par exemple, j'ai une Name
classe avec le champ name
. Une fois que j'ai un Name
objet avec name
initialisé à John Smith, je ne veux pas pouvoir instancier un autre Name
objet également avec le nom de John Smith, ou si l'instanciation a lieu, je veux qu'une référence à l'objet d'origine soit renvoyée plutôt qu'un nouvel objet.
Je suis conscient qu'une façon de le faire est d'avoir une fabrique statique qui contient un Map
de tous les objets Name actuels et la fabrique vérifie qu'un objet avec John Smith comme nom n'existe pas déjà avant de renvoyer une référence à un Name
objet.
Une autre façon dont je pourrais penser du haut de ma tête est d'avoir une carte statique dans la Name
classe et lorsque le constructeur est appelé lançant une exception si la valeur transmise pour name
est déjà utilisée dans un autre objet, mais je suis conscient de lancer des exceptions chez un constructeur est généralement une mauvaise idée .
Y a-t-il d'autres moyens d'y parvenir?
la source
I'm aware that one way of doing this is to have a static factory that holds a Map...
Alors pourquoi tu ne veux pas le faire de cette façon?Réponses:
En fait, vous avez déjà répondu à votre question. Votre première façon devrait être plus efficace ici. L'utilisation
static factory
est toujours préférable queconstructor
partout où vous pensez que vous le pouvez. Ainsi, vous pouvez éviter d'utiliserConstructor
dans ce cas, sinon vous auriezthrow some exception
si une instance existe déjà avec le nom donné.Ainsi, vous pouvez créer une méthode d'usine statique: -
getInstanceWithName(name)
qui obtiendra l'instance déjà disponible avec ce nom, et si elle n'existe pas, elle créera une nouvelle instance et la rendraconstructor
privée, comme cela devrait être fait principalement lorsque vous traitez avecstatic factories
.De plus, pour cela, vous devez maintenir une statique
List
ouMap
toutes les instances uniques créées dans votreFactory
classe.MODIFIER : -
Vous devriez certainement passer par - Java efficace - Élément n ° 1: pensez aux usines statiques plutôt qu'aux constructeurs . Vous ne pouvez pas obtenir de meilleure explication que ce livre.
la source
Les mentions de Java efficace semblent ajouter beaucoup de crédibilité, donc cette réponse s'appuie sur:
Je prendrais un peu de recul et me demander pourquoi vous vous souciez s'il y a plus d'une instance de cet objet de nom.
J'ai rarement besoin de faire ce type de mise en commun d'objets. Je pense que l'OP fait cela afin qu'ils puissent simplement comparer leurs
Name
objets avec==
. Ou utilisez lesName
objets à l'intérieur d'unHashMap
ou similaire comme clé.Si c'est le cas, c'est quelque chose qui peut être résolu par une implémentation correcte de
equals()
.Ainsi:
Une fois cela fait, ce qui suit est vrai:
Je devine que votre objectif, mais cette façon , vous pouvez utiliser la
Name
classe dans les cartes de hachage etc, et ils ne pas avoir à être la même instance exacte.la source
Name
une interfaceNameFactory
avec une méthodeName getByName(String)
NameFactory
avec unMap<String,WeakReference<Name>>
dedanssynchronize
sur la carte par nom à l'intérieur de lagetByName
méthode avant de créer de nouvelles instances deName
Name
interface dans votre implémentation de laNameFactory
Cette approche vous permettrait de vous assurer que:
Name
existe à tout moment,Name
plus longtemps que nécessaire,la source
throw
lorsque le nom identique existe au lieu de renvoyer un objet, ou si vous retournez unnull
objet.destructor
serait pratique.vous devez rendre les constructeurs privés et créer des méthodes comme
getNameInstance(String)
, si un objet du même nom existe déjà (basé sur une classe statique hastable par exemple), vous retournez cette référence, sinon vous créez un nouvel objet en utilisant votre constructeur privé et l'ajoutez à la table de hachagela source
Essayez de suivre. Vous devez garder une trace de chaque objet que vous créez. À cette fin, j'utilise List. Et a rendu le constructeur de classe privé, afin que la pré-vérification puisse être appliquée avant de créer une instance
la source
List
. Ce serait un bon choix pourDictionary<string,UniqueName>
.