Design Patterns: Singleton Basics

Published March 04, 2011 by Ivan Spasov, posted by ivan.spasov
Do you see issues with this article? Let us know.
Advertisement

Design Patterns are among the bread and butter of the good developer's cookbook. Basically, any serious job interview you will have as a Junior to Mid-level programmer, will have a question on Design Patterns in it. They are very important in many regards and essential in others. But no other is quite as controversial as the Singleton Design Pattern. Very rarely have I seen a project that has no implementation of this whatsoever. In this article, I will explain the importance of using this Design Pattern and how to implement it.

Singleton

So what is really the Singleton? Well, it is a Design Pattern that allows us to restrict the class that implements it to have just one instance of itself at all times. In plain terms this means that if we implement Singleton on a class, it will always have just one instance. That's it. That instance will be accessible throughout your code but you will no longer be able to create new instances of the class.

Why should we use it?

There are many reasons. Here is a short list of some "why we should do it" stuff:

  • You will have one singular encapsulation module for the logic of your class that will serve in a way that you can do easy dynamic changes without changing the scope of your programming logic.
  • You can manage a single resource clearly through your code.
  • As the Singleton Design Pattern implements the lazy instantiation, it allows us to get and use it's encapsulated logic as it is needed at runtime.

When do we need Singleton

An implementation of Singleton is needed on classes that would represent something that you use in one form and consistently throughout your project. That would be per say your in-game's scoreboard that monitors your current point count. It's something that you would need during your gameplay experience to increment your score. However, you would need it at the end of your level to calculate your high-score. In that regard, implementing Singleton to your scoreboard class would be perfect. You increment your score and it is stored in the single scoreboard object that you have. When the time comes for us to calculate your in-game high score, we simply access this object and see what you've accumulated. Another classic case would be to store and access the rules of a board game. Normally, if you are developing a regular board game, your rules should be the same all together. There is absolutely no reason for you to create a new object every time and for every game you play. There is no point to have this both from a performance standpoint and from data loss perspective.

But why use Singleton and not a class with static methods?

Singleton is not a replacement for a class with static methods. It's a totally different thing. It's also used in different cases. You would use a class with static methods in situations where you do not need an instance at all. Normally, the static methods are going to be used to do operations with objects that are outside of the class. Generally, the static methods should be implemented in a more generic way as well. They are probably going to be used by multiple logic segments with different parameters altogether. With Singleton, you have a class that should work like a normal one. That's it. Like in the examples above, it's not merely a class containing some methods that are going to be used as tools later on. It is going to contain programming logic on its own. So to talk in examples - you will need Singleton in your board game's rules and in your in-game scoreboard. You would need a static class if you plan to dynamically instantiate reusable UI elements that serve only temporary purpose and are not a part of your core interface.

Singleton Implementations

Here we will take a look at a real implementation of Singleton in Java. Java class implementing Singleton:

public class Scoreboard { 
	public int currentScore; //we will use this for the score later on 
	private static Scoreboard singleton = null; //this we will need for the implementation 
	
	protected Scoreboard(){ //nothing here really. At least for this example. } 
	
	public static Scoreboard instance(){ //this is the method that we are going to use to return the one instance of this class. 				
		if(singleton == null){ singleton = new Scoreboard(); } 
		return singleton; 
	} 
	
} 
	
// Now to use this implementation in another class in order for you to see how it's actually going to happen. 
public class HelloScoreboard{ 
	public static void main(String[] args)
	{ 
		Scoreboard.instance().currentScore = 10; //here we call and set currentScore
		System.out.println(Scoreboard.instance().currentScore.toString()); 
	} 
} 

As seen in the example above, we have the Singleton class Scoreboard. It has its instance() method. Through this method we will get the one instance of this class. Any calls we want to make to the class have to be done through this method. Now, if we take a look at the currentScore variable, we will see that in the main method of HelloScoreboard we are setting it to the value of 10. From this point on, every time we refer to this variable, its value is going to be 10, at least until we change it for some reason. Again, its value can be changed wherever we please.

Singleton Issues

There are some major issues with the Singleton Design Pattern to look out for. If not implemented correctly and in turn, not handled correctly, you may be getting more issues then you would wish.

Multithreading

This is quite possibly one of the biggest issues out there. The problem here is something like this - let's say that you have two threads that for some reason are calling our Singleton object. Since they are two separate threads, we would get a logical paradox - two instances of the Singleton object. That's just not what we want at all. What we want is to have one instance that encapsulates a singular resource and functionality. By having the multithread issue, we completely make the point of the Singleton useless. How can we fix this problem ? Well, generally this is not a problem that can be truly "fixed". It can merely be "mended". We can do that by synchronising/locking the Singleton object. Here is a Java implementation for this:

public class Scoreboard { 
	public int currentScore; //we will use this for the score later on 
	private static Scoreboard singleton = null; //this we will need for the implementation 

	protected Scoreboard(){ //nothing here really. At least for this example. } 
	
	public static Scoreboard instance()
	{ 
	//this is the method that we are going to use to return the one instance of this class. 
	if(singleton == null)
	{ 
		synchronized(Scoreboard.class) 
		{ 
			if(singleton == null){ singleton = new Scoreboard(); } 
		} 
	} 
	
	return singleton; 
	
}

So this is what basically is happening here - on entry, the first thread will check if the singleton instance is null. If it is, then we go to the synchronized lock. When the other thread enters, the creation of the instance is locked. At this point we have another failsafe as well. If/when the second thread manages to get past the lock, when the first thread is done, we have a new check. At this point we block out the issue with the multiple instances.

Unit Testing

This is another major Singleton issue. That's because we would need to test the Singleton instance with every single class that uses it in one way or another. That's just not the idea of the Unit Tests. We want to test just one thing - not one thing and the Singleton. That makes two things and it also makes a corrupt test. Another thing to note here is the fact that the Singleton object has a "state" of a sort. At any time you change something, you change the Singleton's values and thus - it's current state. That makes it near impossible to track the states and the test data in a massive test case. Again, as with the Multithreading issue, here we cannot fix the problem and make it go away. However, there is a workaround that can be used to make things a little bit easier. What can be done is this - for the tests, we can implement an overloaded version of the instance() method that would go with our needs. This is best seen by an example, so let's get into it. We will change up the Scoreboard class and add some additional logic to it - we will have a public double time that would be used for the time we've spent while we accumulate the score. We will also create a class that is going to call both the current score and the time. We are going to call this class EventAtScore and it is going to initiate an event when the player has reached a specific score at a specific time. That will be also the class that we are going to perform the tests on. First off, here is the Scoreboard class:

public class Scoreboard { 
	public int currentScore; //we will use this for the score later on 
	public double time; 
	private static Scoreboard singleton = null; //this we will need for the implementation 
	
	protected Scoreboard(){ //nothing here really. At least for this example. } 
	public static Scoreboard instance(){ //this is the method that we are going to use to return the one instance of this class. 
		if(singleton == null){ 
			synchronized(Scoreboard.class) { 
				if(singleton == null){ singleton = new Scoreboard(); 
			} 
		} 
	} 
	
	return singleton; 
} 

public static Scoreboard instance(int score, int theTime){ //this is the method that we are going to use to return the one instance of this class. //this is the overloaded method that we are going to use for the tests. if(singleton == null){ synchronized(Scoreboard.class) { if(singleton == null){ singleton = new Scoreboard(); singleton.currentScore = score; singleton.time = theTime; } } } return singleton; } } Ok, so now let's go to the EventAtScore class. This would be it's normal construction. public class EventAtScore{ public String eventMessage = ""; public EventAtScore(String defaultMessage){ this.eventMessage = defaultMessage; } public void displayEventMessage(){ Scoreboard theBoard = Scoreboard.instance(); if(theBoard.currentScore == 100 && theBoard.time == 60){ System.out.println(eventMessage); } } } And this is what we would have if we wanted to make a specific test. public class EventAtScore{ public String eventMessage = ""; public EventAtScore(String defaultMessage){ this.eventMessage = defaultMessage; } public void displayEventMessage(){ //Here we use the overloaded version of the instance() method Scoreboard theBoard = Scoreboard.instance(100, 60); if(theBoard.currentScore == 100 && theBoard.time == 60){ System.out.println(eventMessage); } } } 

As seen above, here we are able to produce values in the instance on it's initialization. That suits our needs for testing, at least to some point. There are more flexible and better ways to perform such a test, however I simply wanted to make a point with this. If you are interested in how this can be done properly, you can read up on the following materials:

Debugging and Solving Issues

Since the Singleton can be called at any one point in your code, this makes it really hard to track when your instance got it's values/logics messed up beyond expectations. The resolution here should really be to be careful why, when and where you call your Singleton object but mostly - you need to watch out if your implementation of this pattern is really needed. If you are making too many calls to the Singleton object, you might want to consider another approach.

The Singleton "knows" Too Much

Some times, the deviation of the Sinleton pattern from the traditional OOP understanding is making it an issue of what kind of things it can manipulate. We should not put calculations or any process that has a major role in our code. That's to say that if you have some basic and driving logic, you should by all means NOT include any parts of it inside the Singleton implementation.

Dependency Issues

This is a real blocker as well. When we use the Singleton Design Pattern, we take the risk of making the code too dependent on the object's state/values/logic. Let's say we expect the Singleton object to behave in a certain fashion. We base our logic on that behavior and we think that things are going to go smooth. And it does. Everything is going ok and you are happy that your code works as expected. Well, that's up until you totally forget what you've done with this. And then you decide to make some minor changes here and there. Now, your Singleton object does not behave the way you thought it would. Not only that, now you are totally not in controll of what's happening.

Singleton Implementation in Other Languages

Java is a fairly clear language to port from, however it would be good to take a look at other implementations and how things go there as well.

Singleton in C++

This would be the basic Scoreboard Singleton example from above, only done in C++. #include using namespace std; // This is the Scoreboard class Scoreboard { public: static Scoreboard* singleton;//The Singleton Instance int currentScore; double time; public: static Scoreboard* Instance(); private: Scoreboard(); }; Scoreboard* Scoreboard::singleton = NULL; Scoreboard::Scoreboard() { } Scoreboard* Scoreboard::Instance() { if ( singleton == NULL ) { singleton = new Scoreboard(); } return singleton; }

Singleton in C#

This would be the basic Scoreboard Singleton example from above, only done in C#. using System; public class Scoreboard { private static Scoreboard singleton; public int currentScore; public double time; private Scoreboard(){ } public static Scoreboard Instance { get { if (singleton == null) { singleton = new Scoreboard(); } return singleton; } } }

Interesting Points

I chose Java for most of the examples in the previous chapters because I find it to be really easily portable to other programming languages. If you are doing work with C++ or C# you should have no problem in porting this code. The concepts are basically all the same.

Things You Can Look Up

Here are some online materials that I've fount useful on the Singleton subject:

Conclusion

Using Design Patterns in your code is really something from which you can benefit a lot. Singleton is quite possibly the most common of them all along side with the Factory Design Pattern. Knowing how to implement Singleton can serve you really well.

Article Update Log

14 May 2013: The article was written. 16 May 2013: Added "Things to Look Out For" in the article. 23 May 2013: Refactored the article. Added a couple of issues with the Singleton. 24 May 2013: Added materials to the article. 24 May 2013: Added more code to the Testing section of the article. Added more materials. 24 May 2013: Added basic Singleton implementations for C++ and C#.

Cancel Save
0 Likes 18 Comments

Comments

swiftcoder

Required reading (and I do mean required):

Singleton Considered Stupid

Use your Singletons Wisely

Why Singletons are Evil

Singletons are Pathological Liars

I'm not going to dismiss your efforts out of hand, but if you write a Singleton article that does not provide convincing, well-reasoned rebuttals of the above, it will be ridiculed.

May 23, 2013 05:38 PM
rozz666
Please, stop teaching people about singletons. Why not something more useful like Dependency Injection?

Design Patterns are among the bread and butter of the good developer's cookbook

They aren't. They cause coupling and make other classes difficult to unit-test among other things (which are listed in the post above).

Basically, any serious job interview you will have as a Junior to Mid-level programmer, will have a question on Design Patterns in it.

I refused to write it ;-) (And got the job)
May 23, 2013 06:00 PM
Cornstalks

Wish I could up-vote swiftcoder's comment.

I take issue with this article. It doesn't properly differentiate between a proper singleton and a global. The primary misuse of a singleton is thinking it's equivalent to a global variable (they're kinda related, but I can have multiple global variables). I feel like this article perpetuates that misuse.

Additionally, I take issue with the points in favor of a singleton because they don't point out some things that should seriously be considered:

It is consistent. Throughout your code you will have instant access to your class' object and you will be able to see what's going on with it at runtime.

Globals actually make debugging harder, typically. Multithreading is becoming increasingly important, and synchronizing (and debugging) resources shared between multiple threads is very difficult and tedious. Additionally, this global access can lead to more spaghetti code. These cautions should at least be mentioned.

You will have one singular encapsulation module for the logic of your class that will serve in a way that you can do easy dynamic changes without changing the scope of your programming logic.

Actually, globals increase coupling, which typically makes your code less flexible when it comes to implementation changes. Additionally, I have never found singletons to make changes to an implementation simpler.

This is a very important one – You will save resources and you will have a more optimized performance.

Citation needed. Seriously.

There are other good sides to implementing Singleton, however this is something that you would have to discover for yourselves as this article is more aimed to the beginners.

Beginners are very bad at finding good reasons for design patters and often misuse them. While I support people experimenting and learning on their own, it should be pointed out to the beginner that they might think they have found a "good" use for a singleton that is actually a poor misuse, and another design pattern or architectural change might be much better.

I think an article on singletons is a good idea, but this needs a good amount of work.

May 23, 2013 06:08 PM
Cornstalks

Please, stop teaching people about singletons. Why not something more useful like Dependency Injection?

Design Patterns are among the bread and butter of the good developer's cookbook

They aren't. They cause coupling and make other classes difficult to unit-test among other things (which are listed in the post above).
>

Basically, any serious job interview you will have as a Junior to Mid-level programmer, will have a question on Design Patterns in it.

I refused to write it ;-) (And got the job)

The two quotes here, where the author says "Design Patterns," is a general usage of the term "design patterns" (and doesn't necessarily mean "singletons" specifically).

May 23, 2013 06:16 PM
RobTheBloke

I'm sorry, but if I was interviewing someone for a mid level programming position, and I asked about design patterns. If the first pattern mentioned was "singleton", they would not be getting the job.

I have to say, that of all the uses of a singleton, scoreboard is possibly one of the worst use-cases. So I'll ask you this. I want you to refactor that code to have a "best this week scoreboard", "best this month scoreboard", and a "best of all time scoreboard". This is the problem with singletons. Whilst you might have only one instance today, you can be absolutely certain that won't be the case next week. There is only ever one use case for them, and that is "MyApplication" (and for that, you might as well use a global pointer, instead of all the fluffy faffery that comes from wrapping them behind a pointless class).

May 23, 2013 06:18 PM
Matias Goldberg

I agree with swiftcoder. I don't find the button for peer review :(

This is a very important one – You will save resources and you will have a more optimized performance.

You only save a bit of stack memory by avoiding passing references through functions, may be a bit of heap memory.

But spaghetti code increases, access patterns are difficult to view, and this results in lack of isolation which is vital to optimize performance: access patterns, data locality, prevent doing things twice, and makes multithreading almost impossible.

There are very few cases where Singletons are the first good choice as design pattern to solve a problem. The only one I can think of is a Log manager; and even then, scalability when many threads need to access the Log manager can be questioned.

May 23, 2013 06:20 PM
Cornstalks

There are very few cases where Singletons are the first good choice as design pattern to solve a problem. The only one I can think of is a Log manager; and even then, scalability when many threads need to access the Log manager can be questioned.

I'd argue in favor of a global logger instead of some god-like log manager singleton.

May 23, 2013 06:25 PM
ivan.spasov

Required reading (and I do mean required):

Singleton Considered Stupid

Use your Singletons Wisely

Why Singletons are Evil

Singletons are Pathological Liars

I'm not going to dismiss your efforts out of hand, but if you write a Singleton article that does not provide convincing, well-reasoned rebuttals of the above, it will be ridiculed.

Note taken. In a couple of days I will refactor the article into something with more pros and cons in terms of usage, possible issues and so on.

May 23, 2013 06:59 PM
ivan.spasov

I'm sorry, but if I was interviewing someone for a mid level programming position, and I asked about design patterns. If the first pattern mentioned was "singleton", they would not be getting the job.

I have to say, that of all the uses of a singleton, scoreboard is possibly one of the worst use-cases. So I'll ask you this. I want you to refactor that code to have a "best this week scoreboard", "best this month scoreboard", and a "best of all time scoreboard". This is the problem with singletons. Whilst you might have only one instance today, you can be absolutely certain that won't be the case next week. There is only ever one use case for them, and that is "MyApplication" (and for that, you might as well use a global pointer, instead of all the fluffy faffery that comes from wrapping them behind a pointless class).

I think I might not made it clear enough on the scoreboard topic, for which I'm sorry. By scoreboard I mean an In-game board that calculates your points just on a current game basis, not a leader board.

Thanks for the feedback though.

May 23, 2013 07:00 PM
Ravyne

I applaud the effort, but I fear that you should have chosen a different pattern to explore. At the very least, Singleton is not something you want to design new code around, because its almost never necessary (I struggle to think of even one legitimate use for any program that's not running on bare metal) and it always has consequences for testability and maintainability. Most damning of all though, is that the mere presence of a Singleton promotes a mindset where dependency management goes completely out the window. Global's have the same problem, but at least everyone knows to be wary of them -- Singletons, by virtue of being believed to be 'OOP' and a 'Design Pattern', on the other hand, are incorrectly given a kind of diplomatic immunity.

In truth, Singleton is an Anti-Pattern, this is recognized today by most developers and freely admitted even by the four authors who first popularized it. Unfortunately it had a brief time in the sun when it was adopted in many projects. Unfortunately it has a conceptual appeal that's built on false promises. The fact that it lives on in at least some of those projects is a testament to how difficult it can be to remove from a project -- When you fail to think about dependencies at design time, its a lot of work to fit them in retroactively.

And all of this badness is to say nothing of the very real implementation problems Singleton has in some languages, like C++. In Objective-C its at least possible to create a 'correct' singleton, but at least until C++11, and possibly even still, its literally impossible to guarantee that a singleton is the only one of its kind in a multi-threaded environment. C++11 added a multi-threading primitive that seems at first glance like it might make a safe implementation at least possible, but I'm not sure that it solves Singleton's specific problems.

May 23, 2013 07:06 PM
ivan.spasov

I think an article on singletons is a good idea, but this needs a good amount of work.

Thanks for the feedback. I will refactor the article and put more time into it, along with reference materials.

May 23, 2013 07:08 PM
zaphod2

This version of double check locking actually doesn't work. (see http://en.wikipedia.org/wiki/Double_check_locking) Here a volatile keyword is missing. It's easy to write it the wrong way just like in the article, and it's very language-dependent. Actually in Java there is a way without using locking (using the static member initialization mechanism which is always thread-safe), and in C++ before C++11 it's not even possible (but some threading libraries can be used to put memory barriers to solve the problem). So using this pattern needs a high level understanding of the internal mechanisms of the language, it's not really on beginners' level.

The other anti-pattern is the lock on class. If somebody outside of the class lock on the class too, the two locks may cause a dead-lock. The cause of the dead-lock is that the user doesn't know that a lock is already on the class or object. That's why it's always an anti-patter to lock on class or object. The correct way is to use an private member variable - a simple Object - to synchronize. If needed a getter method can be added to access outsiders to access this object. Here they will know that the class might lock on to this synchronization object, so they can avoid dead-locks.

May 24, 2013 07:00 AM
demonkoryu

Let's keep this balanced. The article, as I see it in its current revision, *does* list a bunch of misgivings with singletons.

There might be a misunderstanding here. Design patterns are a means of communication. Sure, Singleton should be avoided, but when you come across one, it is good if you can give it a name and know its shortcomings and perceived benefits, right? So don't bash this article just for being about singletons.

Also, Singletons are still better than globals (because you have encapsulated the access by getInstance(), which allows at least for a defined construction timing, and might be synchronizable in the presence of multiple threads).

May 24, 2013 08:17 AM
UnshavenBastard

@ rozz666
"They aren't. They cause coupling and make other classes difficult to unit-test among other things (which are listed in the post above)."

Now taking that as general comment on design patterns, I call BS.
Do you use lists? Vectors? Do you use known algorithms as building blocks for your programs, instead of inventing everything from scratch? Then you are relying on design patterns.
GoF coined the name, but "design patterns" are not what they gave examples for or that came after them..., nor did they originate in software development.

May 24, 2013 12:58 PM
NightCreature83

If you want global access to game systems then construct a struct or something that has pointers/references/handles to all of them and pass this in as a parameter on the object creation or update functions. This way you can construct multiple of these that are tailored to the game object that needs it and the coupling is explicit in the function call.

May 24, 2013 01:35 PM
Cornstalks

This version of double check locking actually doesn't work. (see http://en.wikipedia.org/wiki/Double_check_locking) Here a volatile keyword is missing. It's easy to write it the wrong way just like in the article, and it's very language-dependent.

He's not doing "double check locking." He's using the Java synchronized keyword.

Also, Singletons are still better than globals (because you have encapsulated the access by getInstance(), which allows at least for a defined construction timing).

False. You can do the exact same thing with globals:

Foo& globalGetFoo()
{
    static Foo foo;
    return foo;
}
May 24, 2013 01:41 PM
demonkoryu


Were we speaking about global functions or global objects? It is kinda obvious that I'm talking about replacing a global variable, as in




Foo foo; // construction time = ???

vs. a Singleton or your approach.

May 24, 2013 02:29 PM
rip-off

He's not doing "double check locking." He's using the Java synchronized keyword.

There is still a race condition. The Java language specification allows an implementation to perform the assignment of the raw object reference before invoking the constructor.

Say a thread is the first caller and is in the middle of instantiating the object. Assume it has allocated the memory for the object, and assigned it to the variable. It is about to call the constructor, or perhaps is half way though, and is context switched A second thread might see that the reference is not null, returning the reference where the caller may access the object in an invalid state.

May 26, 2013 11:08 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!

In this article we will take a quick look at what is the Singleton Design Pattern, how to use it, when to implement it and what it's good for.

Advertisement
Advertisement