The Singleton

This is the first part in a mini-series of posts around design patterns in software engineering.

The Singleton Design Pattern is one of the most commonly used design patterns in game development. I’ve personally used it in every game project I’ve worked on and it has been extremely valuable. However, in my professional development I’ve yet to find a truly valuable place to use this design pattern. Now that doesn’t mean it has no value in the professional world, it’s just not as commonly used.

So what is the Singleton pattern? What does it do and when/where should it be used? The Singleton pattern is named as such because it is used when you want to enforce your application to only ever have a single instance of an object. The most common place I’ve implemented this design pattern is when I need to implement an object “manager.” This happens frequently in game development.

Imagine your developing a game and in that game enemies are created. There are numerous amounts of these enemies and you need a way to manage these enemies. Having a long list of enemies to keep track of and then pass around to various other functions and objects in the game can quickly turn into a maintenance nightmare. To get around this, we can lump all of these enemies under a single umbrella, a single manager.

Now that we’ve got ourselves a single EnemyManager we need a way to make sure that the next developer that comes along doesn’t go and create a second EnemyManager in another area of the game. Think how hard it would be to get your job done if you had two bosses. The same concept applies here. We don’t want two different managers giving orders to our group of enemies. This is where the Singleton pattern comes into play.

The Singleton pattern ensures that no matter what, no matter when, where, or how… our application will only ever have one single manager. I find that this pattern is most valuable when you have an application that can spring into action in the middle of it’s workflow. For example, think of a game developer working on level 20. Without this pattern, he needs to start the game from the very beginning where the managers are initially setup, walk through all of the start menu’s, just to get to his level so he can test his changes. This can be extremely time consuming.

BUT… if he implements the Singleton pattern, he can create his EnemyManager on every level of his game and the pattern will ensure the manager is created correctly on level 20 and all other levels of the game without any conflicts or duplication. So what does this pattern look like in code? I’ll share an example in .NET:

using System;  
   
public class EnemyManager
{  
   private static EnemyManager instance;
   
   public static EnemyManager Instance  
   {  
      get  
      {  
         if (instance == null)  
         {  
            instance = new EnemyManager();  
         }  
         return instance;  
      }  
   }  
}

So what are we looking at here? Let’s break it down.

private static EnemyManager instance;

This is our single instance of the EnemyManager. You’ll notice that our class itself is not static but does hold a static instance of itself. There are a couple advantages here:

  1. A purely static class can achieve similar results as the Singleton pattern but it cannot implement interfaces that we might use like in the Observer Pattern (we’ll cover in another post).
  2. The Singleton pattern can allow itself to be passed around as an object for Dependency Injection (we’ll cover in another post).

The next piece is how we enforce only a single instance of our EnemyManager to exist and how we protect the one true instance from duplication.

public static EnemyManager Instance  
   {  
      get  
      {  
         if (instance == null)  
         {  
            instance = new EnemyManager();  
         }  
         return instance;  
      }  
   }  

This function is what all other objects will call when they need to grab the EnemyManager instance. When another object calls:

var enemyManager = EnemyManager.Instance;

Our getter will first check if the local ‘instance‘ variable is null. This is where the first check is made to see if an instance of the EnemyManager has already been created at some other time. In our example, we’ll assume this is the first call to EnemyManager and therefore the ‘instance‘ is null. What happens next is we assign a new EnemyManager to the ‘instance‘ variable and then we return it.

Now if we were to make the above call again… when our getter function reaches:

if (instance == null)

We’ll see that we’ve already created our instance of the EnemyManager and instead of creating a new EnemyManager, we’ll return the one that was previously created.

So why does this help our game developer while he’s working on level 20? Well instead of having to create our EnemyManager only at the beginning of the game (to avoid duplication) we can actually call to create our EnemyManager anytime we need it and always guarantee we’ll get the one single instance. This is because even if we start our game on level 20, the Main Menu, or anywhere, our code will make sure that only one EnemyManager ever exists and that we’ll never end up with two managers (having two bosses is such a terrible thought…).

The Singleton pattern is fairly easy to implement but it’s important to know when to use it. Here are the times I’ve found it most useful:

  1. If you know you only ever need a single instance of the object that’s a good sign you’ll want to use the Singleton pattern.
  2. If your application can be started in various states, like level 20 in our example above, and you want to ensure the right objects are created only once.
  3. If you need to have a single instance of an object but you also need to implement Interfaces and/or use Dependency Injection.

If you do find that you need a single instance of an object BUT you do not need to use Interfaces, Dependency Injection, or other Object Oriented Principles then you do have the option to make your entire class static.

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s