public class SingletonObject
{
private SingletonObject()
{
}
public static synchronized SingletonObject getSingletonObject()
{
if (ref == null)
ref = new SingletonObject();
return ref;
}
private static SingletonObject ref;
//other stuff
//Note this method -- esp. the static here
public static void add(whateverObj whatever) {
//do something
}
}
🔒 Locked
[java] Singleton pattern in Java
Advertisement
Original Post
Ok, say you have a thingy like the below code. It seems to me that there's two ways to use a class like this--only one is correct. SingletonObject.add(whatever); SingletonObject.getSingletonObject().add(whatever); Would it be correct to say that this part SHOULD NOT be static? public static void add(whateverObj whatever) Otherwise you can access the singleton object before it's instantiated. Without the static you can only call this: SingletonObject.getSingletonObject().add(whatever); Which should always be safe... Can anyone verify that this is all correct?
Hi,
The add() method must not be static. Also, to ensure you really have a singleton, you could use a static inner class, like this:
However, you used a synchronized approach, so I'm not certain about how it should behave.
Son Of Cain
Edit: [ fixed the source tag ]
The add() method must not be static. Also, to ensure you really have a singleton, you could use a static inner class, like this:
public final class Singleton { private static final class SingletonHolder { private static final Singleton singleton = new Singleton(); } private Singleton() { // Singleton instantiation } private static final Singleton getInstance() { return SingletonHolder.singleton; } public final void add(Object obj) { // method of the Singleton }}However, you used a synchronized approach, so I'm not certain about how it should behave.
Son Of Cain
Edit: [ fixed the source tag ]
For games, do not use synchronized unless you feel very unsafe.
If you feel very unsafe, then you need to redesign in the first place :)
At any rate, remember that synchronized methods will KILL your fps if used at inopportune times. They're best left for server commands and other things that arn't FPS dependent.
If you feel very unsafe, then you need to redesign in the first place :)
At any rate, remember that synchronized methods will KILL your fps if used at inopportune times. They're best left for server commands and other things that arn't FPS dependent.
Are you sure you need an instance of the singleton or are you doing that simply to say "I have implemented the Singleton Pattern"? Wouldn't a class with all static data and methods be enough?
Son of Cain: I'm not seeing any benefit to simply having a
in there. I'm not completely sure when inner classes are exactly loaded (when their container class is loaded or when they are first accessed?) but if the initialization time is important I'd rather set it to null during initialization and create it in getSingleton() or a more specific initialization method...
Son of Cain: I'm not seeing any benefit to simply having a
private static final Singleton singleton = new Singleton();in there. I'm not completely sure when inner classes are exactly loaded (when their container class is loaded or when they are first accessed?) but if the initialization time is important I'd rather set it to null during initialization and create it in getSingleton() or a more specific initialization method...
The use of inner classes to hold Singleton instances is only necessary when you have to ensure a Singleton is created outside the scope of the class providing the instance, but still in the same source file.
It is a bit intrinsic and very specific, but the inner class acts like a factory for the singleton instance. It is only interesting when you have an hierarchy of singletons, like: EquipmentFactory <- WeaponFactory, ArmorFactory, where all of them are singletons.
Son Of Cain
It is a bit intrinsic and very specific, but the inner class acts like a factory for the singleton instance. It is only interesting when you have an hierarchy of singletons, like: EquipmentFactory <- WeaponFactory, ArmorFactory, where all of them are singletons.
Son Of Cain
Quote:
Original post by BitMaster
Are you sure you need an instance of the singleton or are you doing that simply to say "I have implemented the Singleton Pattern"? Wouldn't a class with all static data and methods be enough?
Actually I had the same question myself earlier. I have a few guesses as to the answers, but rather than throwing stuff out I'll wait for someone more enlightened in Java to illustrate why this is better.
I suspect it has mostly to do with future changes: "if you decide that the class should no longer be a singleton, you may simply change the implementation of getInstance."
You use a Singleton because it is a good creational design pattern. Object instantiation should not be used at will, a very well designed app cares about the way its objects are instantiated. A singleton is a class that handles this instatiation, and is the only "point" of your application that can do this instantiation for you.
Singletons are used for "manager" classes, for example, a WindowManager, a PrinterManager, a DBConnectionPool, etc...
Hope it helped a bit =D
Son Of Cain
Singletons are used for "manager" classes, for example, a WindowManager, a PrinterManager, a DBConnectionPool, etc...
Hope it helped a bit =D
Son Of Cain
Found this, and if you're willing to read it, it definitely explains the entire subject in detail.
http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns_p.html
Basically there's two options, the more traditional way, and the "Java way", it seems. (not done reading it yet :p ) Both apparently have tradeoffs.
http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns_p.html
Basically there's two options, the more traditional way, and the "Java way", it seems. (not done reading it yet :p ) Both apparently have tradeoffs.
LoL, nice link! Deals with singletons' implementantion in detail. Seems like everything is covered, concerning implementation.
Private
Private seems to mean "accessible only in this .java file".
What's interesting about it is that the VM does not know about inner/nested classes, so that these are just compiled as separate .classes. But then the VM should not allow access to private members in either direction (inner class may not access outer privates, outer class may not access inner privates, since they are separate classes according to the VM).
Sun's solution to this is to insert extra "package-internal" methods which give other classes direct access to the private members.
Private seems to mean "accessible only in this .java file".
What's interesting about it is that the VM does not know about inner/nested classes, so that these are just compiled as separate .classes. But then the VM should not allow access to private members in either direction (inner class may not access outer privates, outer class may not access inner privates, since they are separate classes according to the VM).
Sun's solution to this is to insert extra "package-internal" methods which give other classes direct access to the private members.
Quote:Wouldn't a factory be a better model for that situation?
Original post by Tebriel Quote:
Original post by BitMaster
Are you sure you need an instance of the singleton or are you doing that simply to say "I have implemented the Singleton Pattern"? Wouldn't a class with all static data and methods be enough?
Actually I had the same question myself earlier. I have a few guesses as to the answers, but rather than throwing stuff out I'll wait for someone more enlightened in Java to illustrate why this is better.
I suspect it has mostly to do with future changes: "if you decide that the class should no longer be a singleton, you may simply change the implementation of getInstance."
The reason you would want to use a singleton is if it you only want one instance per VM and you need to maintain state. If your class is only going to be performing actions (i.e. does not have state), then a class full of static methods would be the approach to take. However, this isn't a good OO approach, but sometimes it's necessary.
I think some of you might be mistaking a factory with a singleton. Factories exist solely to create instances of classes. A good example might be a MonsterFactory that spits out instances of classes derived from a IMonster interface. This factory would not need to maintain any state (unless you're counting how many monster you are creating, but that should be done elsewhere.)
I think some of you might be mistaking a factory with a singleton. Factories exist solely to create instances of classes. A good example might be a MonsterFactory that spits out instances of classes derived from a IMonster interface. This factory would not need to maintain any state (unless you're counting how many monster you are creating, but that should be done elsewhere.)
Factory != Singleton.
But there are times you may wish to create a "Singleton Factory". In my case, our project has a Factory class for resources, which is also a Singleton class, because it needs to maintain state, and its instantiation is expensive, so we want to do it only once and reuse it every time.
Such situations are the reason that causes people to misunderstand the purpose of these design patterns; because game programming often disturbs a programmer's mind, making he do evil things ;)
Son Of Cain
But there are times you may wish to create a "Singleton Factory". In my case, our project has a Factory class for resources, which is also a Singleton class, because it needs to maintain state, and its instantiation is expensive, so we want to do it only once and reuse it every time.
Such situations are the reason that causes people to misunderstand the purpose of these design patterns; because game programming often disturbs a programmer's mind, making he do evil things ;)
Son Of Cain
I don't see why you would want an implementation for this sort in the first place when you can just use the following for Singleton classes.
public final class SingletonClass {
public static int var1 = 0;
public static String name = "I am a Singleton";
}
With Static members.
It seems that you are confusing Singleton with one instance of an object. Just because you only use one instantiation of an object doesn't mean it has to be a singleton you can still keep it with its associated object.
If you want to have the object accessible to the entire program just make the variable that holds it a public Static member in any class within the program that way you aren't wasting time creating your own Singleton class. Or make a "final" class which holds all your related global data. Because thats basically what a Singleton is it's a global instantiation of a class.
Java API uses singletons such as java.lang.System java.lang.Math both of which are "final" classes. I suggest you implement all your singletons this way.
public final class SingletonClass {
public static int var1 = 0;
public static String name = "I am a Singleton";
}
With Static members.
It seems that you are confusing Singleton with one instance of an object. Just because you only use one instantiation of an object doesn't mean it has to be a singleton you can still keep it with its associated object.
If you want to have the object accessible to the entire program just make the variable that holds it a public Static member in any class within the program that way you aren't wasting time creating your own Singleton class. Or make a "final" class which holds all your related global data. Because thats basically what a Singleton is it's a global instantiation of a class.
Java API uses singletons such as java.lang.System java.lang.Math both of which are "final" classes. I suggest you implement all your singletons this way.
As noted, "static classes" are perfectly capable of maintaining state, and they certainly allow you to avoid all the usual problems with just making things "global" - because you can control access via the methods and doing all the usual encapsulation tricks.
The Singleton pattern is already widely regarded as overused - and that's in C++. Java further (for the most part - you can still cause problems with reflection apparently, but if you get bitten by that, I say you deserve it for working some unbelievable combination of deep magics) eliminates one of the main problems that the pattern actually might deal with in C++, i.e. the static order of initialization problem. Classes get all their static stuff initialized at first reference, so there is no chance of something not being uninitialized when it's needed - unless perhaps you have some circular reference problem, but then you'd be screwed *anyway*. You can do any necessary setup work in an init() method, and there is also the option of using a 'static initializer' block (which I personally find quite elegant, except when the init() is required anyway to control timing).
As for "you might decide to make it non-Singleton later", I hold this sort of argument in very low regard - it reeks of YAGNI. My experience has taught me that the best policy is to only design for changes that you have good reason to expect to make.
Note, however, that sometimes a Singleton "instance" is required in Java when exposing a completely static interface - for internal use (thus private) by the class:
The Singleton pattern is already widely regarded as overused - and that's in C++. Java further (for the most part - you can still cause problems with reflection apparently, but if you get bitten by that, I say you deserve it for working some unbelievable combination of deep magics) eliminates one of the main problems that the pattern actually might deal with in C++, i.e. the static order of initialization problem. Classes get all their static stuff initialized at first reference, so there is no chance of something not being uninitialized when it's needed - unless perhaps you have some circular reference problem, but then you'd be screwed *anyway*. You can do any necessary setup work in an init() method, and there is also the option of using a 'static initializer' block (which I personally find quite elegant, except when the init() is required anyway to control timing).
As for "you might decide to make it non-Singleton later", I hold this sort of argument in very low regard - it reeks of YAGNI. My experience has taught me that the best policy is to only design for changes that you have good reason to expect to make.
Note, however, that sometimes a Singleton "instance" is required in Java when exposing a completely static interface - for internal use (thus private) by the class:
public class MainGameLoop extends Canvas implements Runnable { private static Thingy x; // and whatever other data private static MainGameLoop mgl; // <-- here. // Note that since there is only one instance, the actual MGL object can be // "empty", relying on all the other static data members - but we still need // that MGL object for callbacks. Its presence (non-null-ness) also verifies // that class initialization has occurred. public static void main(String[] args) { mgl = new MainGameLoop(); new Thread(mgl).start(); } // These two are public so that AWT/Swing/etc. can see them, but they are // not part of the public interface as far as your app is concerned :/ public void run() { /* implement callback */ } public void paint(Graphics g) { /* implement callback */ } // Part of public interface: request repainting public static void draw() { mgl.repaint(); } // and paint() will be called later}Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement