Sign in to follow this  
tebriel

[java] Singleton pattern in Java

Recommended Posts

Ok, say you have a thingy like the below code.
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
    }
}



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?

Share this post


Link to post
Share on other sites
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:


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 ]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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
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...

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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."

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Correct me if I am wrong, but how will "return SingletonHolder.singleton;" work is SingletonHolder.singleton is declared private? I thought inner classes can access their outher classes private methods and properties, not vica versa.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Quote:
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."
Wouldn't a factory be a better model for that situation?

Share this post


Link to post
Share on other sites
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.)

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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:


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
}

Share this post


Link to post
Share on other sites
So we're saying, if you doing a Singleton in Java, the best way to do it is to simply use static classes? And this has no real disadvantages? Obviously the initialization issue is a non factor. I can't think of any goals of using a Singleton that haven't been addressed here.

Share this post


Link to post
Share on other sites
I don't think all static classes makes it a single. The pattern (as defined by the GOF) like most things OO is about future proofing your code. Just because today you feel that the class should only have a single instance, doesn't mean tomorrow you won't decide actually your going to maintain multiple contexts in your enterprise version and each one is going to need its only instance.

The single static get method returning a statically instantiated single instance of the class is meant to isolate your code from getting dependent on statics. If you're absolutely sure there will never be multiple instances of the object (famous last words) then by all means use an all static class. If not, the Singleton is just a good pattern to avoid problems later.

Kev

Share this post


Link to post
Share on other sites
Quote:
Original post by kg
I don't think all static classes makes it a single.


It indeed doesn't.

Quote:
The pattern (as defined by the GOF) like most things OO is about future proofing your code.


It indeed is.

My argument is that this justification is backwards; if anything, using a design pattern should be the result of reworking something *into* a design pattern, for "past-proofing" - i.e. noticing a problem and making sure it doesn't happen again.

Quote:
Just because today you feel that the class should only have a single instance, doesn't mean tomorrow you won't decide actually your going to maintain multiple contexts in your enterprise version and each one is going to need its only instance.


I have only pity for those who work on projects big enough that this is a real concern (although I acknowledge that such projects certainly do exist). :(

Share this post


Link to post
Share on other sites
Well, I think there's better reasons than just preparing for change:

"A simple approach to this situation is to use static members and methods for the "singleton" functionality. For these elements, no instance is required. The class can be made final with a private constructor in order to prevent any instance of the class from being created.

Unfortunately, this "static-singleton" approach falls short on several counts:

-We may require run-time information to prepare the static-singleton for use. It may be awkward to accomplish this--i.e., we must insure that the static-singleton is properly initialized before each use. This greatly increases the coupling between the static-singleton utility and its clients.

-Methods that are static cannot be used to implement an interface. Hence we lose a great deal of the power of Java's interface entity.

-All references to the singleton must be hard-coded with the name of the class. Hence there is no meaningful way to override the static methods. In other words, all static methods may as well be final."

From

http://radio.weblogs.com/0122027/stories/2003/10/20/implementingTheSingletonPatternInJava.html

Maybe it's a little outdated because it's old, but not sure.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
The pattern (as defined by the GOF) like most things OO is about future proofing your code.


It indeed is.

My argument is that this justification is backwards; if anything, using a design pattern should be the result of reworking something *into* a design pattern, for "past-proofing" - i.e. noticing a problem and making sure it doesn't happen again.
If you design something properly you can usually find many of the possible issues at design time, you can also identify and introduce opportunities for extensibility through design. I prefer to do my past-proofing in advance.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this