Difference between revisions of "Singleton pattern"

From GPWiki
Jump to: navigation, search
m (Reverted edits by Pinkylyn (talk) to last revision by Codehead)
m (Fixed source tags)
Line 1: Line 1:
{{MarkupFix}}
 
 
The singleton pattern is implemented by creating a class with a method that creates a new instance of the object if one does not exist. If one does exist it returns a reference to the object that already exists. To make sure that the object cannot be instantiated any other way the constructor is made either private or protected.
 
The singleton pattern is implemented by creating a class with a method that creates a new instance of the object if one does not exist. If one does exist it returns a reference to the object that already exists. To make sure that the object cannot be instantiated any other way the constructor is made either private or protected.
  
Line 20: Line 19:
  
 
== A Singleton Class Template in C++ ==  
 
== A Singleton Class Template in C++ ==  
<code type="cpp">
+
<source type="cpp">
 
template<class T>
 
template<class T>
 
class Singleton
 
class Singleton
Line 35: Line 34:
 
     static T *m_instance;    // The actual object
 
     static T *m_instance;    // The actual object
 
};
 
};
</code>
+
</source>
  
 
This is the singleton factory, and it's not so big but can be a bit confusing. The implementation of the getSingleton functions returns the instance of the object.
 
This is the singleton factory, and it's not so big but can be a bit confusing. The implementation of the getSingleton functions returns the instance of the object.
Line 42: Line 41:
  
 
To create an instance of an object as singleton just use the static properties of this class:
 
To create an instance of an object as singleton just use the static properties of this class:
<code type="cpp">
+
<source type="cpp">
 
   Singleton<Application>::Instance();
 
   Singleton<Application>::Instance();
</code>
+
</source>
  
 
=== Comment surely the above violates the pattern, due to being able to create a separate none singleton Application instance? ===
 
=== Comment surely the above violates the pattern, due to being able to create a separate none singleton Application instance? ===
Line 53: Line 52:
  
 
To access an instance of the class you just use one of the getSingleton functions.  
 
To access an instance of the class you just use one of the getSingleton functions.  
<code type="cpp">
+
<source type="cpp">
 
   Singleton<Application>::ptr_getSingleton();
 
   Singleton<Application>::ptr_getSingleton();
</code>
+
</source>
 
If there is an instance of this it is returned otherwise an instance should be created.
 
If there is an instance of this it is returned otherwise an instance should be created.
  
Line 63: Line 62:
 
To give an easy example of how to work with the design pattern I will use this easy keyboard listener:
 
To give an easy example of how to work with the design pattern I will use this easy keyboard listener:
  
<code type="cpp">
+
<source type="cpp">
 
class Keyboard_Listener
 
class Keyboard_Listener
 
{
 
{
Line 73: Line 72:
 
     bool m_keys[256]; // not sure how many there are, just a guess
 
     bool m_keys[256]; // not sure how many there are, just a guess
 
};
 
};
</code>
+
</source>
  
 
Assume that there are some function handling user interaction (i.e. the Win32 uses the window procedure).
 
Assume that there are some function handling user interaction (i.e. the Win32 uses the window procedure).
  
 
If a user press the 'k' key and the keyboard listener should get a notice about it, I use the singleton as a tool to inform the one instance of Keyboard_Listener. In pseudo-code it would be something like:
 
If a user press the 'k' key and the keyboard listener should get a notice about it, I use the singleton as a tool to inform the one instance of Keyboard_Listener. In pseudo-code it would be something like:
<code type="cpp">
+
<source type="cpp">
 
   if(key_pressed = 'k')
 
   if(key_pressed = 'k')
 
     Singleton<Keyboard_Listener>::ptrGetSingleton()->keyPressed('k');
 
     Singleton<Keyboard_Listener>::ptrGetSingleton()->keyPressed('k');
</code>
+
</source>
 
To check this in the application I use the singleton to ask if the key is pressed, in pseudo code:
 
To check this in the application I use the singleton to ask if the key is pressed, in pseudo code:
<code type="cpp">
+
<source type="cpp">
 
   if(Singleton<Keyboard_Listener>::ptrGetSingleton()->isKeyPressed('k'))
 
   if(Singleton<Keyboard_Listener>::ptrGetSingleton()->isKeyPressed('k'))
 
     do some stuff;
 
     do some stuff;
</code>
+
</source>
  
 
=== Putting it Together ===
 
=== Putting it Together ===
Line 92: Line 91:
 
This is a small program that makes use of the previous mentioned classes:
 
This is a small program that makes use of the previous mentioned classes:
  
<code type="cpp">
+
<source type="cpp">
 
int main(void)
 
int main(void)
 
{
 
{
Line 111: Line 110:
 
   return 0;
 
   return 0;
 
}
 
}
</code>
+
</source>
  
 
That last example just shows some way of using the singleton, when I know that heavy use will be conducted I create a pointer to hold the instance, consider:
 
That last example just shows some way of using the singleton, when I know that heavy use will be conducted I create a pointer to hold the instance, consider:
<code type="cpp">
+
<source type="cpp">
 
   Singleton<Keyboard_Listener>::ptrGetSingleton()->keyPressed(input);
 
   Singleton<Keyboard_Listener>::ptrGetSingleton()->keyPressed(input);
</code>
+
</source>
 
In opposition to:
 
In opposition to:
<code type="cpp">
+
<source type="cpp">
 
   Keyboard_Listener *k;
 
   Keyboard_Listener *k;
 
   k = Singleton<Keyboard_Listener>::ptrGetSingleton();
 
   k = Singleton<Keyboard_Listener>::ptrGetSingleton();
 
   k->keyPressed;
 
   k->keyPressed;
</code>
+
</source>
 
I believe the latter is a bit easier to work with and the code will be more readable.
 
I believe the latter is a bit easier to work with and the code will be more readable.
  
 
You can also use a typedef-statement to make a shorthand notation of the singleton class. That way, you can use a placeholder name of your own choice to point to singleton class.
 
You can also use a typedef-statement to make a shorthand notation of the singleton class. That way, you can use a placeholder name of your own choice to point to singleton class.
<code type="cpp">
+
<source type="cpp">
 
  typedef Singleton<Keyboard_Listener>::Instance() SingletonKeyboardListener;
 
  typedef Singleton<Keyboard_Listener>::Instance() SingletonKeyboardListener;
 
  #define KeyboardListener SingletonKeyboardListener::ptrGetSingleton()
 
  #define KeyboardListener SingletonKeyboardListener::ptrGetSingleton()
</code>
+
</source>
 
Calling the keyPressed() function will then look like this
 
Calling the keyPressed() function will then look like this
<code type="cpp">
+
<source type="cpp">
 
  KeyboardListener->keyPressed(input);
 
  KeyboardListener->keyPressed(input);
</code>
+
</source>
 
The compiled code will actually look like the following
 
The compiled code will actually look like the following
<code type="cpp">
+
<source type="cpp">
 
  SingletonKeyboardListener::ptrGetSingleton()->keyPressed(input);
 
  SingletonKeyboardListener::ptrGetSingleton()->keyPressed(input);
</code>
+
</source>
 
With <tt>KeyboardListener</tt> being replaced by <tt>SingletonKeyboardListener::ptrGetSingleton()</tt>. You only see the placeholder name, however, so the readability will be improved.
 
With <tt>KeyboardListener</tt> being replaced by <tt>SingletonKeyboardListener::ptrGetSingleton()</tt>. You only see the placeholder name, however, so the readability will be improved.
  

Revision as of 18:39, 4 July 2013

The singleton pattern is implemented by creating a class with a method that creates a new instance of the object if one does not exist. If one does exist it returns a reference to the object that already exists. To make sure that the object cannot be instantiated any other way the constructor is made either private or protected.

Definition

Problem

[1]"Ensure a class only has one instance, and provide a global point of access to it."


Context

  1. All objects need access to a single instance of a class
  2. It is required that no additional instances of the class are created

Solution

  1. Define a class with a private constructor
  2. The class constructs a single instance of itself
  3. Supply a static method that returns a reference to the single instance

UML Diagram

UML Diagram of the Singleton Pattern

A Singleton Class Template in C++

template<class T>
class Singleton
{
  public:
    static T *Instance();           // Create an instance of the object
    static T &ref_getSingleton();   // Get a reference to the object
    static T *ptr_getSingleton();   // Get a pointer to the object
 
  protected:
    Singleton();   // notice that the constructor is NOT public
 
  private:
    static T *m_instance;    // The actual object
};

This is the singleton factory, and it's not so big but can be a bit confusing. The implementation of the getSingleton functions returns the instance of the object.

Creating a Singleton Object

To create an instance of an object as singleton just use the static properties of this class:

  Singleton<Application>::Instance();

Comment surely the above violates the pattern, due to being able to create a separate none singleton Application instance?

To use a singleton version of a class it will have to have one instance, so it would be wise to do a check to see if the instance is created before returning it, and create it if it does not exist.

This means that we will never need an actual member in any class to hold the instance, it's done by the singleton template, I use it for my mouse and keyboard listeners, because there are not often you have the opportunity to have multiples of those.

To access an instance of the class you just use one of the getSingleton functions.

  Singleton<Application>::ptr_getSingleton();

If there is an instance of this it is returned otherwise an instance should be created.

Example of how to use an instanced singleton

(Edit note: I did write this in a confusing way, and did not really understand what I was trying to explain so here are hopefully a better way to explain how to use it)

To give an easy example of how to work with the design pattern I will use this easy keyboard listener:

class Keyboard_Listener
{
  public:
    void keyPressed(const int key) {m_keys[key] = true;} // sets a key status to pressed
    bool isKeyPressed(const int key) {return m_keys[key];} // checks a given keys status
 
  private:
    bool m_keys[256]; // not sure how many there are, just a guess
};

Assume that there are some function handling user interaction (i.e. the Win32 uses the window procedure).

If a user press the 'k' key and the keyboard listener should get a notice about it, I use the singleton as a tool to inform the one instance of Keyboard_Listener. In pseudo-code it would be something like:

  if(key_pressed = 'k')
    Singleton<Keyboard_Listener>::ptrGetSingleton()->keyPressed('k');

To check this in the application I use the singleton to ask if the key is pressed, in pseudo code:

  if(Singleton<Keyboard_Listener>::ptrGetSingleton()->isKeyPressed('k'))
    do some stuff;

Putting it Together

This is a small program that makes use of the previous mentioned classes:

int main(void)
{
  int input;
  Singleton<Keyboard_Listener>::Instance();
 
  while(true)
  {
    cin >> input;
    Singleton<Keyboard_Listener>::ptrGetSingleton()->keyPressed(input);
 
    if(Singleton<Keyboard_Listener>::ptrGetSingleton()->isKeyPressed('q'))
    {
      cout << "you pressed q on your keyboard, exiting..." << endl;
      break;
    }
  }
  return 0;
}

That last example just shows some way of using the singleton, when I know that heavy use will be conducted I create a pointer to hold the instance, consider:

  Singleton<Keyboard_Listener>::ptrGetSingleton()->keyPressed(input);

In opposition to:

  Keyboard_Listener *k;
  k = Singleton<Keyboard_Listener>::ptrGetSingleton();
  k->keyPressed;

I believe the latter is a bit easier to work with and the code will be more readable.

You can also use a typedef-statement to make a shorthand notation of the singleton class. That way, you can use a placeholder name of your own choice to point to singleton class.

 typedef Singleton<Keyboard_Listener>::Instance() SingletonKeyboardListener;
 #define KeyboardListener SingletonKeyboardListener::ptrGetSingleton()

Calling the keyPressed() function will then look like this

 KeyboardListener->keyPressed(input);

The compiled code will actually look like the following

 SingletonKeyboardListener::ptrGetSingleton()->keyPressed(input);

With KeyboardListener being replaced by SingletonKeyboardListener::ptrGetSingleton(). You only see the placeholder name, however, so the readability will be improved.

Be aware that if you're using Microsoft Visual Studio, the IntelliSense function might not be able to parse this setup.

External Links

[1]Erich Gamma et al, "Design Patterns: elements of reusable object-oriented software", Addison Wesley (1995)

external C++ implementation