Saturday, October 1, 2011

singleton pattern implementation


singleton design pattern implementation in C++

Singleton is one of the commonly used patterns in object oriented developments. In this article I am discussing abt this pattern in general and how we can implement this pattern with C++.

Introduction

Suppose we have to use a single object of a class throughout the lifetime of an application. In C++, it is possible to declare a global object, which can be used anywhere inside the program. But a good object oriented design strictly prohibits the use of global variables or methods, since they are against the fundamental principles of object orientation like data encapsulation or data hiding. More over, most latest object oriented programming languages like JAVA or C# do not support global variables or functions.

Another practical solution to get a single object is by declaring a class, which contains only static methods. A static class is loaded into memory when the execution of the program starts and it remains there till the application ends. Remember that for invoking a static method of a class, it is not necessary to create an instance of the class. But remember that a class with only static methods and variables are not a good object oriented design. A class of static methods unfortunately breaks down to a list of functions or utilities.

When we want to create only one instance of a class in a truly object oriented fashion by adhering to the basic principles of object oriented programming, the Singleton patterns are used. The Singleton Pattern comes under that classification of Creational Pattern, which deals with the best ways to create objects. The Singleton Design pattern is used, where only one instance of an object is needed throughout the lifetime of an application. The Singleton class is instantiated at the time of first access and same instance is used thereafter till the application quits.

There are very good non-software examples available in real world for Singleton patterns. The office of the Principal of my college is a Singleton. The University specifies the means by which a principal is selected, limits the term of office, and defines the order of succession. As a result, there can be at most one active principal at any given time. Regardless of the personal identity of the principal, the title, "The Principal" is a global point of access that identifies the person in the office.

The Singletons are often used to control access to resources such as database connections or sockets. Suppose we have a license for only one connection for our database. A Singleton connection object makes sure that only one connection can be made at any time.

It is pretty easy to implement the Singleton Pattern in any object oriented programming languages like C++, JAVA or C#. There are lots of different ways to implement the Singleton Pattern. But by using a private constructor and a static method to create and return an instance of the class is a popular way for implementing Singleton Pattern. The UML representation of a Singleton Pattern is shown below.
The Singleton design pattern ensures only one instance of a class in an application (more generally it provides a framework to control the instantiations of a particular class, so that more than one instantiation could be provided, but under the control of the Singleton class). The GoF book discusses Singleton patterns, while Meyers discusses general techniques for limiting object instantiation in item 26 of More Effective C++. In Singleton classes, all of the regular constructors are publicly disabled (put in the private section), and access to the singleton object is through a static method which creates a controlled instance of the class and returns a reference to this controlled instance.

An example that Meyers uses is:

class Printer {
   public:
      static Printer& thePrinter();
      // ...
   private:
      Printer(); // no public creation of Printer objects
      Printer (const Printer& rhs);
      // ...
};
Printer& Printer::thePrinter() {
   static Printer p;
   return p;
}
// example usage:
Printer::thePrinter().reset();
Printer::thePrinter().submitJob(buffer);

Note that this example implementation code will not work if the Singleton is accessed in a multi-threaded environment, since there may be two (or more) threads trying to simultaneously access the Singleton for the first time, causing a conflict in the static instance creation. Some form of mutex protection must be provided in this scenario.

There are many flavors of Singletone and quite a few subtle complexities, although the general principle of the pattern makes it one of the easiest to understand. One potential complexity is controlled destruction of the internal Singleton instance (i.e. when is it destructed and in what order compared to other Singletons or global objects).

Example:

No comments:

Post a Comment