Reputation: 2662
Consider a class that contains a property Name
inside. I would like the class to be implemented as singleton, and I want the Name
to be set only once (so it can be assigned once but not changed later).
Should I assign it with a constructor (and give it only get
accessor, without set
) or create a separate "instance variable" for "Name" and a proper method that will work only once?
The first option would force me to pass a string
argument to the GetInstance()
method every time I call it, while the second one does not seem too elegant for me (as I wouldn't know if "Name" was already set - so I'd need to call this method every time I try to get an instance anyway.) Am I taking a wrong approach? Is there a good practice for such case?
Upvotes: 0
Views: 946
Reputation: 1148
The problem with passing the value into getInstance()
every time is that all calling classes will have to know where the value for Name comes from and how to fetch it. Maybe they do all have this access, but then it makes it redundant storing this data on the singleton object as all callers already know its value.
Assuming that some callers know the value, and others don't, you could use a property similar to the way that you have suggested yourself:
public class MySingleton
{
// Singleton properties omitted
private string name;
public string name
{
get{return this.name;}
set
{
if(String.IsNullOrEmpty(this.name))
name = value;
// The exception could be left out, depending on how critical this is
else
throw new exception("The property 'name' can only be set once");
}
}
}
This assumes that neither null or String.Empty
are valid assignations for your property and its still not the most elegant solution, so perhaps there is a different approach altogether.
Perhaps the constructor for the singleton could fetch the required value, rather than being passed the value:
public MySingleton()
{
name = configuration.getName(); // or wherever it is coming from
}
This way the calling classes can always assume that the singleton has a valid value for Name
, but without caring where it comes from. If possible, I think this would be my preferred choice
Upvotes: 1