• Register

Game Developer for AllocateThis! Studios.

  • View media
  • View media
  • View media
RSS My Blogs

Design Patterns

Today is going to be our first discussion on design patterns. So first of all I will explain what design patterns are and what they are not. Design patterns make it easier to reuse successful techniques. A pattern can be used to solve a problem with your architecture without compromising reusability. Sometimes they can even be self documenting which helps in maintaining the code. The design patterns I will be posting are all proven to be successful and have been implemented more than once in different systems.

Design patterns are not like coding conventions that just make people happy about how you name variables, or whether or not you put your curly braces on a new line. The patterns are techniques with a goal of solving a problem, you may even find that a pattern I discuss is a technique you already know but didn't know it was recognized as a proven design pattern.
So where should we start?

I figured we should start off easy and show the Singleton design pattern.

So what is a singleton?

A Singleton is a single instance of an object.

Why would you need a Singleton?

A Singleton is great for objects that should only have a single instance like a logger. For instance say you have a logger class but all throughout your code as you call the logger you are making new instances while in different classes or methods. You could easily have several instances having write locks if your logging to a file. Or say in an example I'll show later you may want a Singleton GameManager and it be the authoratitive class that determines the state of the game as well as the rules for the game. If you have multiple GameManager instances you could easily create multiple game states.

C++ Header File
#define SINGLETON CSingleton::Instance()

class CSingleton
{
public:
static CSingleton* Instance();

protected:
CSingleton();
private:
static CSingleton* _instance;
~CSingleton(); // The destructor

};

Lets take a closer look at this header file.

static CSingleton* Instance();

I have a method call to retrieve the singleton instance, we will use this call to grab the single instance of our class, and if it doesn't exist we will make one.

protected:

CSingleton();

Next we have the singleton constructor in the protected put simply we don't want members outside of the class to be able to call our constructor. This is what makes this design unique. So now you can't have a call like this in your main or other methods:

CSingleton singleton = new CSingleton();

So lets look at the private section:

static CSingleton* _instance;
~CSingleton(); // The destructor

we create a static Singleton pointer instance which gets set in the implementation method Instance(). We return the _instance from the Instance() method. And the destructor which is used to delete the pointer after we are done with the class.

Lastly, on the top of the file you see my Macro #define

#define SINGLETON CSingleton::Instance()

Basically this is a convience macro used to make calling the singleton's method easy in any class. It is really just an easy way of grabbing the instance of the class. for example if I had a method called Log(std::string sMessage) in my CSingleton class, I could just call this method from my main or another class to log an error or specify some kind of trace message.

void CSomeClass::SomeMethod()
{

SINGLETON->log("Log my awesome message");

}


Now on to the Implementation File


C++ Implementation File

#include "Singleton.h"

CSingleton* CSingleton::_instance = 0;

CSingleton* CSingleton::Instance()
{
if(_instance == 0)
{
_instance = new CSingleton();
}

return _instance;
}

CSingleton::CSingleton()
{
// Enter stuff you want to initialize
// It will only be initialized once
}

// The Destructor
CSingleton::~CSingleton()
{
// Lets delete the singleton.

if(_instance != NULL)
{
delete _instance;
}
}
Okay lets go through this from to to bottom so looking at the first line:

CSingleton* CSingleton::_instance = 0;

Should be very straight forward, we are setting the CSingleton pointer _instance to zero. Basically just initializing it so we can do a conditional check on it.


Next lets look at the Instance() method implementation

CSingleton* CSingleton::Instance()
{
if(_instance == 0)
{
_instance = new CSingleton();
}

return _instance;
}

So right away you see that the Instance() method returns a type CSingleton*. Then we do a conditional if check to see if the _instance pointer equals zero, and if it does we want to create the instance of the CSingleton class. but if we have already created the instance instead of creating a new instance it will just return the _instance that we have made prior.


On to the Constructor....

CSingleton::CSingleton()
{

// Enter stuff you want to initialize
// It will only be initialized once

}

The Constructor shouldn't need much explanation, in this case its completly empty, but you would generally do your initializing in it, and remember that it will only initialize once.


Finally, lets talk about the destructor...

CSingleton::~CSingleton()
{
// Lets delete the singleton.

if(_instance != NULL)
{
delete _instance;
}
}

Generally I use the boost smart pointer, which if you have never heard of I will explain at a later date. but in this case once we are closing the app we should check if the _instance is not null, meaning check just incase we deleted the instance somewhere else (This should never happen but just as a safe guard). then say delete _instance; and that is it.

So now that C# is all the rage I figured why not make a sample of the implementation of the Singleton in C#.

C# Implementation
using System;

public class Singleton
{
private static Singleton instance;

private Singleton() {}

public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
Now this should look very similar to the C++ code we have above except that it is in the C# syntax, and we are using the get to retrieve the instance but it does the same thing as above. The only caveat to this is implementation is that it is not thread safe. So how would we go about making it thread safe? Well look below at the thread safe implementation.
using System;

public class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();

private Singleton() {}

public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}

return instance;
}
}
}
Now normally according to .NET Framework and MSDN you would set this as a sealed class, I am not a huge fan of sealed. As it in a sense makes you turn off inheritance. You can check out this article for more information on (WILL RE ADD ONCE AFTER MY 7 DAY PROBATION)


But there you have it a nice thread safe implementation of your Singleton in C#. I will be making a YouTube video of the C++ implementation and C# implementation. For the C# one I will be making a GameManager for Unity3D. Once it is up I will post it here at the bottom. Hope you guys enjoyed the post and stay tuned for our next Design Pattern!

Farewell, and Happy Coding!



Sources:

Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma (Author), Richard Helm (Author), Ralph Johnson (Author), John Vlissides (Author)

(WILL RE ADD ONCE AFTER MY 7 DAY PROBATION) - C# - Implementing a Singleton

Start a group Groups
AllocateThis! Studios

AllocateThis! Studios

1 member Developer

An Indie Game Company that develops games for mobile and PC.

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account:

X