Ich suche nach verschiedenen Möglichkeiten, um sicherzustellen, dass jede Instanz einer bestimmten Klasse eine eindeutig identifizierbare Instanz ist.
Zum Beispiel habe ich eine Name
Klasse mit dem Feld name
. Wenn ich ein Name
Objekt habe, das mit name
John Smith initialisiert wurde, möchte ich nicht in der Lage sein, ein anderes Name
Objekt auch mit dem Namen John Smith zu instanziieren, oder wenn eine Instanziierung stattfindet, möchte ich, dass ein Verweis auf das ursprüngliche Objekt eher zurückgegeben wird als ein neues Objekt.
Mir ist bewusst, dass eine Möglichkeit dazu darin besteht, eine statische Factory zu haben, die Map
alle aktuellen Namensobjekte enthält, und die Factory prüft, ob ein Objekt mit dem Namen John Smith noch nicht vorhanden ist, bevor sie einen Verweis auf a zurückgibt Name
Objekt.
Eine andere Möglichkeit, die mir auf den ersten Blick einfällt, besteht darin, eine statische Map in der Name
Klasse zu haben und beim Aufruf des Konstruktors eine Ausnahme auszulösen, wenn der übergebene Wert für name
bereits in einem anderen Objekt verwendet wird. Allerdings sind mir Ausnahmen bekannt in einem Konstruktor ist in der Regel eine schlechte Idee .
Gibt es andere Möglichkeiten, dies zu erreichen?
quelle
I'm aware that one way of doing this is to have a static factory that holds a Map...
Warum willst du es nicht so machen?Antworten:
Eigentlich haben Sie Ihre Frage schon beantwortet. Ihr erster Weg sollte hier effektiver sein. Verwenden
static factory
ist immer vorzuziehen,constructor
wo immer Sie denken, dass Sie können. Sie könnenConstructor
in diesem Fall also vermeiden , etwas anderes zu verwenden,throw some exception
wenn bereits eine Instanz mit dem angegebenen Namen vorhanden ist.Sie können also eine statische Factory-Methode erstellen: - Mit
getInstanceWithName(name)
dieser Methode wird die bereits verfügbare Instanz mit diesem Namen abgerufen. Wenn sie nicht vorhanden ist, wird eine neue Instanz erstellt undconstructor
als private Instanz definiert, wie dies normalerweise bei der Arbeit mit dieser Instanz der Fall iststatic factories
.Dazu müssen Sie in Ihrer Klasse eine statische
List
oderMap
alle eindeutigen Instanzen verwalten, die erstellt wurdenFactory
.EDIT : -
Sie sollten auf jeden Fall durchlaufen - Effektives Java - Punkt 1: Betrachten Sie statische Fabriken über Konstruktoren . Eine bessere Erklärung als dieses Buch gibt es nicht.
quelle
Erwähnungen von effektivem Java scheinen eine Menge Glaubwürdigkeit zu verleihen, daher stützt sich diese Antwort auf:
Ich würde einen Schritt zurücktreten und fragen, warum es Sie interessiert, wenn es mehr als eine Instanz dieses Namensobjekts gibt.
Ich muss diese Art von Objektpooling selten durchführen. Ich vermute, dass das OP dies tut, damit sie ihre
Name
Objekte einfach vergleichen können==
. Oder verwenden Sie dieName
Objekte in aHashMap
oder ähnlichem als Schlüssel.Wenn ja, ist dies etwas, das durch die ordnungsgemäße Implementierung von
equals()
gelöst werden kann .Wie so:
Sobald dies erledigt ist, gilt Folgendes:
Ich vermute Ihr Ziel, aber auf diese Weise können Sie die
Name
Klasse in Hash-Maps usw. verwenden, und sie müssen nicht genau die gleiche Instanz sein.quelle
Name
eine SchnittstelleNameFactory
mit einer MethodeName getByName(String)
NameFactory
mit einemMap<String,WeakReference<Name>>
darinsynchronize
auf der Karte nach Namen innerhalb dergetByName
Methode, bevor Sie neue Instanzen von erstellenName
Name
Schnittstelle in Ihrer Implementierung vonNameFactory
Mit diesem Ansatz können Sie Folgendes sicherstellen:
Name
vorhanden.Name
länger bleiben als nötig.quelle
throw
wenn der gleiche Name anstelle der Rücksendung ein Objekt vorhanden ist , oder wenn Sie eine Rückkehrnull
Objekt.destructor
nützlich wäre.Sie sollten die Konstruktoren als privat
getNameInstance(String)
kennzeichnen und Methoden erstellen, z. B. wenn bereits ein Objekt mit demselben Namen vorhanden ist (basierend auf einer statischen Klasse, die Sie hastabilisieren können), geben Sie diesen Verweis zurück. Andernfalls erstellen Sie ein neues Objekt mit Ihrem privaten Konstruktor und fügen es hinzu zur Hashtabellequelle
Versuchen Sie folgendes. Sie müssen jedes Objekt, das Sie erstellen, im Auge behalten. Zu diesem Zweck benutze ich List. Und den Klassenkonstruktor privat gemacht, damit die Vorabprüfung vor dem Erstellen einer Instanz angewendet werden kann
quelle
List
. Dies wäre eine gute Passform fürDictionary<string,UniqueName>
.