The life-cycle of the Singleton

When it comes to the discovery and usage of the Singleton pattern, it goes a little something like:

  1. Find out we can have global variables in OOP.
  2. Make everything you’ll only need one of a Singleton.
  3. Realize that was a really bad idea and cut back.
  4. Eventually, you’ll only have singletons for a very special couple of things.

I reached number four. But it turns out there is a hidden 5th:

Realize you never actually required anything be a singleton.

This was pointed out to me by jalf on a question regarding singleton use. I suggested option 4, while jalf persisted number 5. The arguments were as follows (abridged):

jalf: Singletons are global variables with unnecessary restraints.
GMan: Singletons are global variables that help maintain initialization order.
jalf: You can do that with a global function. Singleton’s enforce a silly no-copies rule.
GMan: But it wouldn’t make sense to have more than one memory manager/thread pool.
jalf: So then don’t make more than one.

At that point, it was clear: there doesn’t exist a class such that it be key there only ever exist one. Sure, creating more than one instance of a class could be a strange waste of resources, but is preventing that really worth the intrusive and complex nature of a singleton?

I removed the singletons from my code, and replaced them with a global wrapper instead. All classes and types could have lazy-initialization just be declaring it a bit differently:

int globalInt;
foo globalFoo;

global<int> globalInt;
global<foo> globalFoo;

These are lazily initialized variables, now. It avoids both the static initialization fiasco along with the restraints of a singleton. And best of all, the code is cleaner.

If you’re at stage four in your singleton relationship, then cut the string. You really don’t need this pattern.

EDIT:

It should be noted that jalf has elaborated on this point in his own blog.

4 Responses to “The life-cycle of the Singleton”

  1. Viet Says:

    Thanks for sharing. I didn’t realize the 5th hidden stage. Please kindly elaborate on

    global globalInt;

    How can I get this? Thanks in advance!

  2. GMan Says:

    It’s actually not trivial to make such a utility (consider most problems with singletons were creating the global safely, not forcing one instance.)

    I may write an article on this in the future when I explore the idea fully.

  3. Viet Says:

    Great! I’ll be awaiting your future article on safe globals.

  4. GMan Says:

    Good timing. :) I’m actually close to proposing my take on a Boost.Global library to the mailing list. You can download the source (I will also post it on the blog) and take a look.

Leave a Reply