Reputation: 23
I'm rather new to Java and struggling about following:
I have a class that creates objects, in which different data (lists) are kept. The data is always assigned to one very identifier (attribute):
class History {
private String identifier;
private ArrayList<ObjectsRelatedToIdentifier> objectsRelatedToIdentifier;
}
I now need to have one object per identifier (X, Y, Z, etc.) but only one. It should not be possible to instantiate two objects with identifier X.
Also, i need to be able to access those objects from other objects. How do I keep "hold" of them?
The internals of those objects is always the same, only the identifier is different and of course the values in the ArrayList.
Is there some kind of "multiple singleton pattern" or a combination of different patterns?
Upvotes: 2
Views: 751
Reputation: 27702
Just follow the singleton pattern but, instead of having just one reference to the common object, keep a map of references indexed by the identifier.
public class MultiSingle {
public static MultiSingle getInstance(String id)
{
MultiSingle ret = id2obj.get(id);
if(ret == null)
{
ret = new MultiSingle();
id2obj.put(id,ret);
}
return ret;
}
private MultiSingle()
{
//Your stuff
}
private static Map<String, MultiSingle> id2obj = new HashMap<>();
}
Upvotes: 1
Reputation: 33076
Use a factory to create objects and have it track all the values.
First make the constructor package local:
public class YourObject {
private String uniqueValue;
YourObject(String id) {
this.uniqueValue = id;
}
}
Then have others instance the object using YourObjectFactory::create
:
public final class YourObjectFactory {
private static Map<String, YourObject> instances = new HashMap<>();
public static synchronized YourObject create(String id) {
YourObject oldInstance = instances.get(id);
if (oldInstance == null) {
YourObject newInstance = new YourObject(id);
instances.put(id, newInstance);
return newInstance;
} else {
return oldInstance;
}
}
}
like with:
YourObject woah = YourObjectFactory.create("Woah!");
In this implementation, a reference to the instance will be returned if it was already created for a given id
. You can raise an exception instead if you deem it more appropriate.
Upvotes: 0
Reputation: 68720
What you want isn't really a singleton, it's more of an Object Pool.
Much like a database Connection Pool. Whenever you try to connec to a database that you've connected to before, you'll get a Connection
from the pool. If you try to connect to a new database, a new Connection
will be created for you and added to the pool.
Internally, the ConnectionPool
(or an HistoryPool
) could be implemented with an hash map, that maps the connection string (or, in your case, the identifier) to the connection object (an instance of History
).
Upvotes: 0
Reputation: 201497
Is there some kind of "multiple singleton pattern" or a combination of different patterns?
Yes, the multiton pattern. Which (from Wikipedia) is,
In software engineering, the multiton pattern is a design pattern similar to the singleton, which allows only one instance of a class to be created. The multiton pattern expands on the singleton concept to manage a map of named instances as key-value pairs.
Upvotes: 1
Reputation: 7586
Put your History objects into HashMap
:
HashMap<String key,History h> map = new HashMap<String key,History h>();
map.put("X",new History());
Upvotes: 1