Home > Design > Singleton Considerations

Singleton Considerations

I started out writing this post as a series of comments on StackOverflow but I decided there just wasn’t enough room to discuss this.

The original question is titled “What is so bad about Singletons?” and can be found at StackOverflow here. The answer receiving the most upvotes was:

Paraphrased from Brian Button:

  1. They are generally used as a global instance, why is that so bad? Because you hide the dependencies of your application in your code, instead of exposing them through the interfaces. Making something global to avoid passing it around is a code smell.
  2. They violate the Single Responsibility Principle: by virtue of the fact that they control their own creation and life-cycle.
  3. They inherently cause code to be tightly coupled. This makes faking them out under test rather difficult in many cases.
  4. They carry state around for the lifetime of the app. Another hit to testing since you can end up with a situation where tests need to be ordered which is a big no no for unit tests. Why? Because each unit test should be independent from the other.

1:

I agree with him on that. In cases, where such a dependency is not obvious by the classes name, the dependency should be injected. Injecting Singleton Instances into classes proves a wrong usage of the pattern.

2:

All Objects need to control their life-cycle in a way. All objects need to have a constructor/destructor. This is even more true in non-managed languages such as C++/Objective-C where you are responsible of releasing your collaborators (Java and .NET programmers tend to forget that).  A Singleton’s life-cycle is assumed to be the same as the application’s, so I don’t see the need to “control” that here. Most Singleton implementations are using a lazy-load mechanism to instantiate themselves. This is trivial and their life-cycle is unlikely to change, or else you shouldn’t use Singleton.

3:

The GoF Singleton Pattern description includes the following: (p.128, Consequences 3.)

Permits refinement of operations and representation. The Singleton class may be subclassed, and it’s easy to configure an application with an instance of this extended class. You can configure the application with an instance of the class you need at run-time“.

Contrary to static classes, Singleton Instances are normal classes and can therefore inherit from base classes and/or implement interfaces. In order to make a Singleton Instance swappable, you can either choose to inject (“initialize”) a “to-be-Singleton Instance” into the Singleton or lazy-load it based on some configuration info. Throwing exceptions on requests made before the Singleton Instance was initialized (and optionally, when an attempt is made to reinitialize it) ensures the same semantic behaviour as that of a simple Singleton Class. Eventually, this is no different from how an IoC Container would deal with Objects whose lifetime shall be that of a Singleton.

4:

If your Singleton carries a significant global state, don’t use Singleton. This includes persistent storage such as Databases, Files etc. Note that log files are an exception to that. In most cases their state isn’t significant for the behaviour of the Application. Good examples for the usage of Singletons are PrintSpoolers (fire and forget).

About these ads
Categories: Design
  1. runefs
    August 25, 2010 at 14:42

    Your point 1 and 3 contradicts each other. In 1 you say there’ no life time management or trivial management because it’s the application life time but in 3 you introduce exceptions to be thrown when the Singleton is expected to exist but doesn’t aka when there’s a life cycle management error.

    AD 1 & 4) How would you name a singleton for a PrinterSpool so that it’s obvious that the class called “BusinessReports” depends on it? (BusinessReports depends on PDFViewer that in turn depends on Printer for printing purposes and Printer depends on PrintSpool)

    How would you inject a singleton? Remember no one but the singleton can create it. If some one else can create it it’s no longer a Singleton (some other instance is controlling the number of created instances)

    Deriving from Singleton breaks the Singleton-ness (implementing an interface in a singleton class does not)
    “and optionally, when an attempt is made to reinitialize it” is no option since not throwing would result in at least two “singletons”

  2. sleeplessnerd
    September 5, 2011 at 02:44

    Passing stuff in isn’t really that hard. I dont see the benefits other than not having to explicitly declare the dependency and therefore being able to change stuff after designing the api.

  3. June 28, 2012 at 01:08

    Interesting discussion, just stopped by from SO thread to say thanks for sharing your thoughts on this topic.

  4. funatlearn
    January 15, 2013 at 18:08

    To the point no. 3, How would you inject singleton instance from DI/IoC? A standard singleton implementation does not allow public constructors (which are needed for majority of Di/Ioc)

  5. November 10, 2013 at 13:05

    >> How would you inject singleton instance from DI/IoC?
    Having single instance globally is called Singleton.
    Having a private constructor enforces this above rule. It doesn’t need to be enforced, if you use dependency injection (DI) properly.

  6. SapoChule
    September 29, 2014 at 16:27

    You really shot off target on 2:[ All Objects need to control their life-cycle in a way. All objects need to have a constructor/destructor. ] – A constructor and destructor defines HOW the object is constructed/destructed. Object life-cycle is WHEN the object is constructed and destructed. No, objects shouldn’t control their life-cycle, no no no no, stop advocating the use of the Singleton, it makes writing unit tests as painful as birth

  1. August 8, 2013 at 13:01

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: