Singleton vs static

P

Philipp

Hello,
I've been reading a little about the difference between using a
singleton pattern vs using a static class (ie all methods are static,
ctor is private, state is in static vars).

A lot of blogs show that there are differences between these two
approaches. I can't understand most of them. Any help would be appreciated.

---

Assertion found on web: "The Singleton pattern is useful when the object
itself needs to keep some state. If no such thing is needed, a static
method can do the job as well."

My POV: No, you can put a state in a static var and access it through
static methods.

---

Flexibility of the factory mehod: You can simply create two subclasses,
MyDevelopmentSingleton and MyProductionSingleton, and let your
MySingleton.getinstance() function decide which to return.

My POV: If you declare you ctor private to enforce the singleton
pattern, you cannot subclass it. If you declare the ctor protected, is
it still a true singleton? Users can then create more than one object...

---

Assertion found on web: The main difference between static and Singleton
classes is that static classes don’t ever get initialised.

My POV: I don't understand. What about static initializers?

---

So, in the end it's not clear for me why one should prefer the Singleton
pattern over the static class (should I?). I mean

SingletonClass.getInstance().setSomething(int a);
SingletonClass.getInstance().getSomething();

is quite quivalent to

StaticClass.setSomething(int a);
StaticClass.getSomething();


Any comments are welcome. Best regards
Phil
 
A

Andreas Leitgeb

Philipp said:
A lot of blogs show that there are differences between these two
approaches. I can't understand most of them. Any help would be appreciated.
My POV: If you declare you ctor private to enforce the singleton
pattern, you cannot subclass it.

Well, you would of course not make it private then but "default". This
means it's better hidden than protected, but in your own package, you
(as the designer of that package&class) can still derive from it.

My impression is, that this is the only (principially) relevant argument
for Singleton-classes. The other ones failed to convince me just like you.
But others' mileage may vary...
 
P

Patricia Shanahan

Philipp said:
Hello,
I've been reading a little about the difference between using a
singleton pattern vs using a static class (ie all methods are static,
ctor is private, state is in static vars).

For me, the key issue is one you do not mention, what happens if you
find out it needs to be a non-singleton, for example to support more
flexible testing.

If you use static, you need to change every use of any method in the
class. If you use a singleton, you at most have to change getInstance
calls. Many of those may not need to be changed if there is a default
instance returned by the parameterless getInstance method.

Patricia
 
L

Lew

Philipp said:
My POV: No, you can put a state in a static var and access it through
static methods.

Which breaks as soon as two different instances need different state at the
same time.

All-static-method classes get away with it by /not/ maintaining any state.
It's a pattern for stateless methods.
 
A

andrewmcdonagh

Hello,
Hi,

I've been reading a little about the difference between using a
singleton pattern vs using a static class (ie all methods are static,
ctor is private, state is in static vars).

A lot of blogs show that there are differences between these two
approaches. I can't understand most of them. Any help would be appreciated.

No worries, I can't understand most blogs either - mainly because most
blogs suck.
---

Assertion found on web: "The Singleton pattern is useful when the object
itself needs to keep some state. If no such thing is needed, a static
method can do the job as well."

My POV: No, you can put a state in a static var and access it through
static methods.

The singleton pattern is useful to ensure that 'only one instance of
that class' is ever created and available during the running of your
application. Its almost irrelevant that it holds member variables and
their state, as this is more of a value added capability.

The most common implementation of a singleton in Java uses a factory
method to return the instance.

class MySingleton {
private static MySingleton instance = new MySingleton();
//private constructor here....

public MySingleton getInstance() { return instance; }
}

This ensures that only one instance of MySingleton Class is avaiable
to the application at runtime.

Then these singletons then tend to be given member variables to store
that are needed through out the application. e.g. property file
values loaded into it, main frame of the UI, etc....


For this kind of ability, a singleton is a natural (though not
necessarily nice) choice to make.

A static method is only useful for utility methods (like the
getInstance factory method above) where they dont need to access
instance variables or maintain state.

Yes its true you could maintain state in static variables which static
methods call, but then you have basically create a class that can't be
used like any other class - polymorphically.

There is a middle ground though.

Its called the MonoState pattern. This is where you have a call with
only static member variables, all methods are still not static
methods. This means evey use of the class has to create an instance
of it, but every instance shares the same static member variable
state. This hybrid pattern allows the benefits of polymorphism to
continue, whilst allowing the system wide state of the member
variables. Its useful if you are doing a lot of JUnit tests, where you
need to override the monostate behaviour for your tests.

That said...the whole issue is moot... Basically if you need only one
instance of the class... then just create one, not two.

The biggest problem with Singletons, Static methods, Monostates etc...
is that people are lazy. They can't think how to designt he system so
that the dont have to pass around all over the place, the single
instance of a class they created, so they go with a singleton, not
because they actually need a singleton...just because its easier. Its
less coding and requires less thinking.

---

Flexibility of the factory mehod: You can simply create two subclasses,
MyDevelopmentSingleton and MyProductionSingleton, and let your
MySingleton.getinstance() function decide which to return.

My POV: If you declare you ctor private to enforce the singleton
pattern, you cannot subclass it. If you declare the ctor protected, is
it still a true singleton? Users can then create more than one object...

---

Assertion found on web: The main difference between static and Singleton
classes is that static classes don't ever get initialised.

My POV: I don't understand. What about static initializers?

---

So, in the end it's not clear for me why one should prefer the Singleton
pattern over the static class (should I?). I mean

SingletonClass.getInstance().setSomething(int a);
SingletonClass.getInstance().getSomething();

is quite quivalent to

StaticClass.setSomething(int a);
StaticClass.getSomething();

Any comments are welcome. Best regards
Phil


Best regards

Andrew
 
P

Philipp

Lew said:
Which breaks as soon as two different instances need different state at
the same time.

If you need _two_ instances its not a singleton anymore, is it?
 
P

Philipp

Thank you all for your answers. I understand now that two things make
the singleton more interesting than the all-static function class.
(please correct if I'm wrong)

Polymorphism: You could make a singleton which extends a non-singleton
(eg. a unique UI-Frame which extends JFrame), and still use it with all
methods which require the superclass as argument(ie. JFrame).

For testing, it could be nice to replace the singleton by another test
version. Possibly, you could choose in the getInstance() factory to
produce a subclass based on some global application state (eg. DEBUG
state). This is most easily done with a singleton.

Phil
 
L

Lew

Philipp said:
OK sorry. I don't understand.
Do you mean I have to synchronize the access to the static var?

Synchronization won't help. The problem generally is the problem with global
variables.

<sscce source="testit/SnoGlobal.java" >
package testit;

import java.util.Random;

class Foo
{
volatile private static String global;
public static void setGlobal( String g )
{ global = g; }
public static String getGlobal()
{ return global; }
}

/** SnoGlobal - The answer to "What's a good global?"
*/
public class SnoGlobal implements Runnable
{
private final String name;
public SnoGlobal( String f )
{
this.name = f;
}
@Override
public void run()
{
Random ran = new Random();

for ( int ix = 0; ix < 3; ++ix)
{
Foo.setGlobal( name );
try
{
Thread.sleep( ran.nextInt( 5000 ) );
}
catch ( InterruptedException ex )
{
System.err.println( "Interrupted "+ name );
}
System.out.println( "Instance " + name + ", global " +
Foo.getGlobal() );
}
}

public static void main( String [] args )
{
SnoGlobal baron = new SnoGlobal( "baron" );
SnoGlobal tobar = new SnoGlobal( "tobar" );
new Thread( baron ).start();
new Thread( tobar ).start();
}
}
</sscce>

Output:
Instance tobar, global tobar
Instance baron, global tobar
Instance tobar, global baron
Instance tobar, global tobar
Instance baron, global tobar
Instance baron, global baron
 
W

Wayne

Philipp said:
Thank you all for your answers. I understand now that two things make
the singleton more interesting than the all-static function class.
(please correct if I'm wrong)

Polymorphism: You could make a singleton which extends a non-singleton
(eg. a unique UI-Frame which extends JFrame), and still use it with all
methods which require the superclass as argument(ie. JFrame).

For testing, it could be nice to replace the singleton by another test
version. Possibly, you could choose in the getInstance() factory to
produce a subclass based on some global application state (eg. DEBUG
state). This is most easily done with a singleton.

Phil

No one else mentioned it, but static final primitive fields
are factored out in Java; to change one requires recompiling ALL
classes that potentially use that singleton. You avoid this
headache using a proper singleton pattern.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top