A core solution to a recurring problem
Pattern Name
an easy to understand label to provide a common vocabulary
Problem
explanation of when to apply the pattern
Solution
general arrangement of elements (classes and objects)
Consequences
results and trade-offs of the particular solution
Ways of instantiating objects
The conventional way
New classname;
Design Pattern way
Abstract Factory
Builder
Factory Method
Prototype
Singleton
Pattern Name
Singleton
Problem (when to use this pattern)
When you need to ensure a class only has one instance, and provide a global point to access it
i.e. NOT a global variable!
When the sole instance should be sub-classed, and doing so does not require modification of existing code
Solution 1
The passive/pleading approach
Graphics.h looks like the following:
class Graphics
{
public:
Graphics ();
~Graphics ();
};
// in a comment, place the following:
// make sure to instantiate only one of these!
extern Graphics theGraphics;
Of course, there can be many Graphics instantiated, the compiler cant stop it.
You cant be sure someone will actually read your comments
The Ill force them myself approach
Graphics.h looks like this:
class Graphics
{
public:
static void DrawRect ();
static void DrawCircle ();
static void DrawBitmap ();
};
and code like this:
Graphics::DrawRect ();
How can you subclass zoo?
class WindowsGraphics : public Graphics
{
public:
static void DrawRect (); // error!
static void DrawCircle (); // error!
static void DrawBitmap (); // error!
};
Solution 3
Make the constructor inaccessible
Make a member function that returns an instance pointer
Graphics.h looks like this:
class Graphics
{
public:
static Graphics *MakeInstance ();
protected:
Graphics (); // the world cant make them at will
static Graphics *instance;
};
Graphics.cpp looks like this:
Graphics *Graphics::instance = 0 ;
Graphics *
Graphics::MakeInstance ()
{
if (NULL == instance)
instance = new Graphics;
return instance;
}
code looks like this,
for every place that wants to use Graphics:
Graphics *gPtr = Graphics::MakeInstance ();
The root class will have to know about all derived classes
Graphics
Graphics::MakeInstance ()
{
switch (someValue)
{
case WINDOWS:
instance = new WIndowsGraphics;
break;
default:
instance = new Graphics;
break;
}
return instance;
}
Consequences
The Singleton class can control how, when and what actually gets instantiated
It can decide to not return the pointer (I dont know why, but it could)
Its easy to subclass when needed
Allows for a change of mind and instantiation of many instances easily
Ooop. It would be handy to have many of them
Allows for polymorphism, where all static member functionality does not
Can also be used to limit the number (greater than 1) of instantiated objects
Keeping track of a registry of available sub-classes can get nutty
Since instance is a pointer, no object is actually created until MakeInstance () is called
Summary
Use Singleton to guarantee a single instance of a class
It defines a well-known access point for all clients
It allows simple subclassing (without clients having to modifying their code)
This allows coding for change, because
You can change your mind about it being a single object
You can change your mind about what object is actually instantiated