views:

7866

answers:

21

Name the design considerations in deciding between use of a singleton versus a static class. In doing this, you're kind of forced to contrast the two, so whatever contrasts you can come up with are also useful in showing your thought process! Also, every interviewer likes to see illustrative examples. :)

A: 

When the single class needs state. Singletons maintain a global state, static classes do not.

For instance, making a helper around a registry class: If you have changable hive (HKey Current User vs. HKEY Local Machine) you could go:

RegistryEditor editor = RegistryEditor.GetInstance();
editor.Hive = LocalMachine

Now any further calls to that singleton will operate on the Local Machine hive. Otherwise, using a static class, you would have to specify that Local Machine hive everytiem, or have a method like ReadSubkeyFromLocalMachine.

David Sokol
I would argue against using a Singleton in this way... It is very dangerous to keep states lingering, because the next caller might forget to set the hive, and write to the registry in the wrong hive...:-( This is probably an example of misuse that makes people think Singletons are bad.
ufotds
+7  A: 

I'd argue the only difference is syntax: MySingleton.Current.Whatever() vs MySingleton.Whatever(). The state, as David mentioned, is ultimately "static" in either case.


EDIT: The bury brigade came over from digg ... anyhow, I thought of a case that would require a singleton. Static classes cannot inherit from a base class nor implement an interface (at least in .Net they cannot). So if you require this functionality then you must use a singleton.

xanadont
+2  A: 

If by "static class" you mean a class that has only static variables, then they actually can maintain state. My understanding is the that the only difference would be how you access this thing. For example:

MySingleton().getInstance().doSomething();

versus

MySingleton.doSomething();

The internals of MySingleton will obviously be different between them but, thread-safety issues aside, they will both perform the same with regards to the client code.

Outlaw Programmer
Singletons are themselves objects -> they can be passed as arguments.
SealedSun
+1  A: 

Singletons should never be used (unless you consider a class with no mutable state a singleton). "static classes" should have no mutable state, other than perhaps thread-safe caches and the like.

Pretty much any example of a singleton shows how not to do it.

Tom Hawtin - tackline
What about manager classes controlling hardware resources? What about log file classes?
RJFalconer
A: 

If a singleton is something you can dispose of, to clean up after it, you can consider it when it's a limited resource (ie. only 1 of it) that you don't need all the time, and have some kind of memory or resource cost when it is allocated.

The cleanup code looks more natural when you have a singleton, as opposed to a static class containing static state fields.

The code, however, will look kind of the same either way so if you have more specific reasons for asking, perhaps you should elaborate.

Lasse V. Karlsen
A: 

The two can be quite similar, but remember that the true Singleton must itself be instantiated (granted, once) and then served. A PHP database class that returns an instance of mysqli is not really a Singleton (as some people call it), because it is returning an instance of another class, not an instance of the class that has the instance as a static member.

So, if you're writing a new class that you plan to allow only one instance of in your code, you might as well write it as a Singleton. Think of it as writing a plain-jane class and adding to it to facilitate the single-instantiation requirement. If you're using someone else's class that you can't modify (like mysqli), you should be using a static class (even if you fail to prefix its definition with the keyword).

Brian Warshaw
A: 

Singletons are more flexible, which can be useful in cases where you want the Instance method to return different concrete subclasses of the Singleton's type based on some context.

ElectricDialect
A: 

@ElectricDialect: You can type members of static classes and use polymorphism there, as well. That doesn't require a Singleton, either.

Brian Warshaw
How do you do this?
recursive
A: 

Static classes can't be passed around as arguments; instances of a singleton can be. As mentioned in other answers, watch for threading issues with static classes.

rp

rp
A: 

A singleton may have a constructor and destructor. Depending on your language, the constructor may be called automatically the first time your singleton is used, or never if your singleton is not used at all. A static class would have no such automatic initialization.

Once a reference to a singleton object is obtained, it can be used just like any other object. The client code may not even need to know its using a singleton if a reference to the singleton is stored earlier on:

Foo foo = Foo.getInstance();
doSomeWork(foo); // doSomeWork wont even know Foo is a singleton

This obviously makes things easier when you choose to ditch the Singleton pattern in favor of a real pattern, like IoC.

landon9720
A: 

Use the singleton pattern when you need to compute something at runtime that you would compute at compile time if you could, like lookup tables.

Jared Updike
A: 

Think of a singleton like a service. It's an object which provides a specific set of functionality. E.g.

ObjectFactory.getInstance().makeObject();

The object factory is an object which performs a specific service.

By contrast, a class full of static methods is a collection of actions that you might want to perform, organised in a related group (The class). E.g.

StringUtils.reverseString("Hello");
StringUtils.concat("Hello", "World");

The StringUtils example here is a collection of functionality that can be applied anywhere. The singleton factory object is a specific type of object with a clear responsibility that can be created and passed around where required.

izb
+3  A: 

One of my favorite discussions about this issue is here.

To summarize the flexibility advantages of a Singleton:

  • a Singleton can be easily converted into a factory
  • a Singleton can be easily modified to return different subclasses
  • this can result in a more maintainable application

This document is removed. Here is a link to Internet Archive Wayback machine. I place it as regular text, as SO does not parse it as link. Copy the link bellow and paste in a browser:

http://web.archive.org/web/20080118174633/http://www.bitchwhocodes.com/archives/2006/04/singleton_vs_st.html

ElectricDialect
+3  A: 

Static classes are instantiated at runtime. This could be time consuming. Singletons can be instantiated only when needed.

dmo
Singletons are instantiated at runtime too...
recursive
A: 

I think a place where Singleton will make more sense than the static class is when you have to construct a pool of costly resources (like database connections). You would not be interested in creating the pool if noone ever uses them (static class will means that you do the costly work when class is loaded).

Jagmal
+1  A: 

A static class with a load of static variables is a bit of a hack.

/**
 * Grotty static semaphore
 **/
 public static class Ugly {

   private static int count;

   public synchronized static void increment(){
        count++;
   }

   public synchronized static void decrement(){
        count--;
        if( count<0 ) {
            count=0;
        }
   }

   public synchronized static boolean isClear(){
         return count==0;    

    }
   }

A singleton with an actual instance is better.

/**
 * Grotty static semaphore
 **/
 public static class LessUgly {
   private static LessUgly instance;

   private int count;

   private LessUgly(){
   }

   public static synchronized getInstance(){
     if( instance==null){
        instance = new LessUgly();
     }
     return instance;
   }
   public synchronized void increment(){
        count++;
   }

   public synchronized void decrement(){
        count--;
        if( count<0 ) {
            count=0;
        }
   }

   public synchronized boolean isClear(){
         return count==0;    

    }
   }

The state is in ONLY in the instance.

So the singleton can be modified later to do pooling, thread-local instances etc. And none of the already written code needs to change to get the benefit.

public static class LessUgly { private static Hashtable session; private static FIFO freePool = new FIFO(); private static final POOL_SIZE=5; private int count;

   private LessUgly(){
   }

   public static synchronized getInstance(){
     if( session==null){
        session = new Hashtable<String,LessUgly>(POOL_SIZE);
        for( int i=0; i < POOL_SIZE; i++){
           LessUgly instance = new LessUgly();  
           freePool.add( instance)
        }
     }
     LessUgly instance = session.get( Session.getSessionID());
     if( instance == null){
        instance = freePool.read();
     }
     if( instance==null){
         // TODO search sessions for expired ones. Return spares to the freePool. 
         //FIXME took too long to write example in blog editor.
     }
     return instance;
   }

It's possible to do something similar with a static class but there will be per-call overhead in the indirect dispatch.

You can get the instance and pass it to a function as an argument. This lets code be directed to the "right" singleton. We know you'll only need one of it... until you don't.

The big benefit is that stateful singletons can be made thread safe, whereas a static class cannot, unless you modify it to be a secret singleton.

Tim Williscroft
+17  A: 
  • Singletons can implement interfaces and inherit from other classes
  • A singletons can be lazy loaded. Only when it is actually needed. That's very handy if the initialisation includes expensive resource loading or database connections.
  • Singeltons offer an actual object
  • Singletons can be extended into a factory. The object management behind the scenes is abstract so it's better maintainable and results in better code.
Tobias
A: 

Singletons should not be used in the same way as static classes. In essense,

MyStaticClass.GetInstance().DoSomething();

is essentially the same as

MyStaticClass.DoSomething();

What you should actually be doing is treating the singleton as just another object. If a service requires an instance of the singleton type, then pass that instance in the constructor:

var svc = new MyComplexServce(MyStaticClass.GetInstance());

The service should not be aware that the object is a singleton, and should treat the object as just an object.

The object can certainly be implemented, as an implementation detail and as an aspect of overall configuration, as a singleton if that makes things easier. But the things that use the object should not have to know whether the object is a singleton or not.

Justice
A: 

A singleton is also a good idea if you want to force efficient caching of data. for example, I have a class that looks up definitions in an xml document. Since parsing the document can take a while, I set up a cache of definitions (I use SoftReferences to avoid outOfmemeoryErrors). If the desired definition is not in the cache I do the expensive xml parsing. Otherwise I return a copy from the cache. Since having multiple caches would mean I still might have to load the same definition multiple times, I need to have a static cache. I choose to implement this class as a singleton so that I could write the class using only normal (non-static) data members. This allows me to still create an istantiation of the class should I need it for some reason (serialization, unit testing, etc.)

KitsuneYMG
+2  A: 

How about "avoid both"? Singletons and static classes:

  • May introduce global state
  • Get tightly coupled to multiple other classes
  • Hide dependencies
  • Can make unit testing classes in isolation difficult

Instead, look into Dependency Injection and Inversion of Control Container libraries. Several of the IoC libraries will handle lifetime management for you.

(As always, there are exceptions, such as static math classes.)

TrueWill
Small nits: singleton classes are compatible with dependency injection techniques (just inject them in to their dependent classes and they don't need to hard-code anything) -- this permits mocking and testing in isolation. They are also a valid design pattern for managing resources that are known to be limited platform wide. (The classic example is printers that have no contention management.)
cdleary
@cdleary - agreed; however the classic implementation often leaves Singleton.getInstance() throughout the codebase. "Singletons" to manage resources, caches, etc. can be implemented with POCOs/POJOs and IoC Container frameworks that support lifetime management (register the type as container lifetime and every resolution will get the same instance).
TrueWill
If you want to give your Singletons a proper burial, go to http://www.singletonfuneralservice.com/
TrueWill
+1  A: 

Depends on the Context,,

Saman