Reputation: 18861
I don't want to use singleton, but I simply cannot allow more than one instance of my class.
Would you consider this a good approach, and if not, what's a better way?
public class SoundSystem {
private static boolean instanceCreated = false;
public SoundSystem() {
if(instanceCreated) {
throw new IllegalStateException("Only one instance can be created.");
}
instanceCreated = true;
}
}
Upvotes: 3
Views: 2695
Reputation: 7910
The solution you posted allows a garden variety "race-condition". Two entities trying to create a your SoundSystem at the same time could end up both creating an instance.
Maybe making all the methods of and variables of SoundSystem static will get you what you desire, but it is hard to know without more information.
Upvotes: 0
Reputation: 5315
No, it's not a good approach.
Let's take a quick example in a context of multi-threading.
Thread 1 instantiates SoundSystem
, the if(instanceCreated)
returns false, before changing instanceCreated
to true the scheduler interrupts Thread 1. Now Thread 2 can also instantiates SoundSystem
since isInstanceCreated
is false at that time.
But at the end, both thread will have a different instance.
Upvotes: 1
Reputation: 1206
You can use an enum, if you are willing to make all of your fields final
. This too has some "code smell" to it though. It will protect against multi-threaded issues, but does have the restriction that all of your SoundSystem
instance variables would need to be final.
public enum SoundSystem {
INSTANCE("Hello", "World");
private final Object field1;
private final Object field2;
private SoundSystem(Object field1, Object field2) {
this.field1 = field1;
this.field2 = field2;
}
@Override
public String toString() {
return field1.toString() + " " + field2.toString();
}
public Object getField1() {
return this.field1;
}
public Object getField2() {
return this.field2;
}
//etc., etc.
}
You can then use SoundSystem.INSTANCE
to gain access to your singleton item
Upvotes: 0
Reputation: 40335
This is a singleton, even if you are not enforcing it in the "traditional" manner. I don't recommend this approach, and I think you should find another way.
For example, why not create a single SoundSystem
instance when your program starts? You don't need to explicitly enforce its single-ness, just pass that instance along to other objects that need access to the sound system. As a bonus, this also lets you easily drop in support for different types of SoundSystem
s if you need it some day (a nice little extra benefit, even if you don't need this).
On top of all this, will the OpanAL initialization itself fail if you try and initialize multiple SoundSystem
s? If not, then there's not really a reason to place an artificial limit. If so, then you can just let OpanAL determine what is and isn't an error. But in any case, it wouldn't be a risk if you simply just create one instance and pass it off instead of letting all your application classes query the instance themselves.
Be careful you don't fall into the XY Problem trap here. Singletons aren't inherently evil, but for some reason they are frequently misused, hence the general advice against them. There is usually a cleaner way, and these cleaner ways usually come with a lot of bonus added benefit. Think about the actual problem you are trying to solve / situation you are trying to avoid here.
Upvotes: 3