Thoughts on Singletons

Intro

There are sometimes where some things keep bugging me in terms of programming. I often keep asking myself and others about utilizing the best techniques to solve various programming problems and applying certain concepts in a program.

Most answers I keep reading/hearing tend towards the “wow” factor. Which is something like “I don’t know exactly why, but it would be cooler if you did it like this”. I don’t usually listen to any recommendation regarding programming practices if it isn’t backed up by strong arguments as to how it may affect me in the long or short term as far as my projects are concerned. As programming languages are evolving, so do practices utilizing those languages, and often, as good programmers as we may be, we may sometimes find ourselves lagging behind others who may be less experienced, but better listeners.

Let’s face it. Many of us have utilized a not-so-well-thought technique in favor of completing a task within a certain amount of time. In other words, we have all sacrificed the chance to use good programming practices in need of being “faster”. Usually, this results in usable code, that may be improved in later versions. Less often, this isn’t the case.

As far as programming practices go, there are few of them that have received as much love and hate as Singletons.

Singletons are not a new programming concept, and describe objects that are instantiated only once within the application, and are deallocated when the application ends. Their purpose is to hold global variables and execute application-wide actions that apply to any part of the program. The singleton pattern can be applied into any OOP language, and it has been the subject of debates for years.

Singletons: The Good parts

I believe that the most intriguing part of implementing a singleton is that it’s easy. Consider the following code in C#:

public class Singleton  {
    private static final Singleton instance = new Singleton();
    // Private constructor prevents instantiation from other classes
    private Singleton() {
    }
    public static Singleton getInstance() {
        return instance;
    }
}

And there we have it! Now every function or variable we put in there will be available application-wide using “Singleton.getInstance()”. No extra coding necessary.

A similar singleton in C++ would have this code:

#include <string>
using namespace std;
class Log {
  public:
    static Log* Inst(char* filename);
    void Logging(string message);
    void Initialize();
    ~Log();
  protected:
    Log(); // constructor
  private:
    static Log* pInstance;
};Log* Log::Inst(){
  static Log inst;
  return &inst;
}

The above code is creating a Singleton that serves as a logging object. Then, in your main program, you can call this singleton like this (C++):

Log::Inst()->Logging("Warning: Just a log!");

Code in C# should be equivalent. 

Singletons can also get rid of spaghetti code, since you define a single object that will hold every global variable, eliminating the need to use sparse global variables into .h or .hh files or any other type of file. In API-driven GUI programming, this is a life-saver.

Singletons: The bad parts

Consider the above code. Take a look at it again. And again. Notice the hidden trap in it? No? Then, you should ask yourself about one thing:

What about thread safety? What happens if two threads execute “getInstance()” at the same time? Or try to access a variable? A real life example would be a Singleton holding a global array that holds an number of database entries. An object tries to enumerate the objects of the array (searching?) and another object tries to add an object at the same time.

The application crashes, possibly destroying your database back-end (it’s possible, depending on your configuration and database. In large projects, when a singleton is starting to behave strangely, you won’t even know what hit you. The application will crash, and most probably the debugger will not provide you with the necessary information to track down the bug.

Therefore, you must implement some kind of locking mechanism to the singleton object or/and its properties. That surely adds complexity to your application. In some applications, the level of added complexity is so great, that it would be best of think of alternatives instead of using singletons.

The above C++ code could be altered so that it loks like this:

Log* Log::pInstance = NULL;
Log* Log::Inst(char* filename){
  if(pInstance == NULL){
    pInstance = new Log(filename);
  }
  return pInstance;
}
Log::Log(){ // constructor
  Initialize(); // you can ignore this function
}

Fortunately, the ‘new’ operator is thread-safe, so if you want to implement Singletons in a multithreaded application, you should use the above code. But even this won’t save you from all the headaches of improper concurrency. If your singleton holds global variables or shortcuts to other important objects inside the application than can be accesses simultaneously from two threads, the application will crash. So, inide the Log::Inst() function (or the function that returns you the instance of your singleton in general) you must write a thread-safe code, that will return the instance of the singleton ensuring that it will perform only one job at a time, or at least, that it will work with multiple threads safely.

Another major drawback of using singletons is unit-testing. Unit testing concerns testing of specific parts of a program, without running the application as a whole. A global variable surely adds a high level of complexity in terms of unit testing, rendering almost impossible to implement simple unit testing in medium to large scale applications without sacrificing much development time.

Are singletons bad or good?

Simple question with no definitive answer. There are many programmers that say no to singletons, and they have very good reasons for doing so. In general, you can use singletons in your applications only if you are absolutely sure that what you want to do cannot be implemented any other way, and if it can, it will cause more problems than it will solve.

In order to know wether you must use singletons or not, you should ask yourself these questions:

— Will every part of your application use your singleton unchanged exactly the same way?
— Will every part of your application need only one instance of this class?
— Will this class be able to handle multithreading or at least, will you be able to use it in away that multithreading will not be an issue?

If you answered “yes” to all these questions, then you may have found yourself a singleton. If not, then you need to rethink your strategy, and your coding in general.

However, even if you need to create a singleton, consider solving the problems that singleton solves by creating a plain object.

For example a great idea for a singleton object is a logging service inside the application. Every object will have access to the same singleton which will be responsible for application console logging. There is no point in creating different application objects for a service that does the same for every object inside an application.

The same can be applied for a local database singleton that will handle I/O from and to a local database file. However, in our database concept, we can toss our singleton in the trash, and create a plain old-fashioned but sophisticated class, that will be attached to any object that will perform database I/O and use variables whose scope is the owner object alone.

Using the latest Singleton workaround example, in a GUI parent-child controller paradigm (such as a stack of a navigation controller in an iOS UINavigationControler stack or a tree of any kind) you can create this database object at the top of the navigation stack, and pass it as an argument from parent to every child. That also solves a problem arising with the singleton. When a child in the tree hierarchy changes the database’s data, every parent is notified of the change instantly, without having to fetch the data from any singleton. Since the database object is actually a passed variable between parents and children, each change is reflected globally. With singletons, you would have to post some kind of notification or use delegation (depending on the language you use) in order to make every GUI element depending on any object of the hierarchy reflect any kind of change.

I wrote this little note because I just wanted to share my thoughts on this. You should know that I stand on the side of using singletons, but with great care. I use them for a long time now, but as I dive deeper into advanced programming concepts, and undertake larger and larger projects, I have found that hard way that there are numerous factors you must take into account before and while using them, and lately, I am finding more and more alternatives to singletons. I mainly rely on singletons to hold application variables like BOOL and INT, and maybe implement a global database system (having implemented thread-safety improvements).

That said, I must also admit that singletons have also caused me headaches, mostly when I must think using multiple threads.

Small Appendix: Ensuring thread – Safety in Cocoa

Singletons are nothing new in Cocoa. They exist from the very beginning of the Objective C programming language itself. NSFileManager, for example, is used only as a singleton. So does NSUserDefaults. This is a non thread safe way of creating a singleton in Cocoa

static MySingleton *sharedInstance = nil; 
+ (void)initialize
{
    if (sharedInstance == nil)
        sharedInstance = [[self alloc] init];
}
+ (id)sharedMySingleton
{
    //Already set by +initialize.
    return sharedInstance;
}
+ (id)allocWithZone:(NSZone*)zone
{
    //Usually already set by +initialize.
    @synchronized(self) {
        if (sharedInstance) {
            //The caller expects to receive a new object, so implicitly retain it
            //to balance out the eventual release message.
            return [sharedInstance retain];
        } else {
            //When not already set, +initialize is our caller.
            //It's creating the shared instance, let this go through.
            return [super allocWithZone:zone];
        }
    }
}
- (id)init
{
    //If sharedInstance is nil, +initialize is our caller, so initialize the instance.
    //If it is not nil, simply return the instance without re-initializing it.
    if (sharedInstance == nil) {
    self = [super init];
    if (self) {
            //Initialize the instance here.
        }
    }
    return self;
}

This was the most used way of creating singletons in Cocoa and iOS. Works exactly the same way. Don’t let the @synchronized command fool you. This object is NOT thread safe. @synchronized implements a simple locking mechanism, but in a true multithreaded environment, you will need an thread queue. That is, a queue that performs an operation, and then performs the next one, without interfering with the main thread.

And that’s exactly what the below code is doing:

+ (id)sharedMySingleton
{
    static dispatch_once_t pred;
    static MySingleton *mySingleton = nil;
    dispatch_once(&pred, ^{ mySingleton = [[self alloc] init]; });
    return mySingleton;
}

You can get rid of the above code and substitute it with the last one. You see, it seems that Apple has finally found a simple solution for all out multithreading headaches named “Grand Central Dispatch” which works with blocks of code and takes care of multithreading by itself. The last code is as thread-safe as a singleton can be in Cocoa and iOS. You can use this method on OS X 10.6 and iOS 4 and newer.