Singleton design pattern for beginners.

Background - 

When you want to restrict your class from creating more than one object at a time or when you have a requirement where you want to maintain a single session on web application, who will record all your activity, or a logger application (one logger for all sub modules), please use singleton design pattern.

For example –
     a.       When you do online shopping. Your global login get create and it remembers all item picked by you during your active session.
     b.      We create single log file for any S/W application per day. It will help us to debug issues. It will be very messy if we create thousands of log file on each usages of different module/functionality. Debugging will become hell.

We have plenty of examples where we use singleton design patter in our S/W. This is very easy, popular and useful design patter.

We can also restrict the number of object to be initialized. For example, I would like to have only 7 objects to get created, any attempted to create more than 7 should get warning message.

We can implement it through singleton design pattern by having a count increment variable in it.

Singleton design pattern -

Very important thing are,
    1.       We will declare constructor as private, So that other should not be able to create the object.
    2.       Our code will have a static method, which will return the pointer/reference of existing object.
    3.       Have a counter variable if there is a requirement of creating certain number of objects (for ex - 7).

UML representation –


Example –



 /**************************************************************************************
 /*
 * Pro4
 * Singleton design pattern.
 * (c) 2015 Kunjesh Singh Baghel, All Rights Reserved.
 * https://sites.google.com/site/kunjeshsinghbaghel/
 *
 *
 ***************************************************************************************/
 
 //*************************************************************************************
 // Header files
 #include<iostream>
  using namespace std;
 
 //*************************************************************************************
 // 
 class  Singleton
 {
  private:
  //zero argument copy constructor.
  Singleton(){}
  //Copy constructor.
  Singleton(Singleton &){}
  // overloaded assignment operator.
  const Singleton& operator = (Singleton &){}
  // single pointer which will get refereed in all the places.
  static Singleton *mp_singleton;
  
 
 public:
  static Singleton* GetInstance();
 };

 //*************************************************************************************
 // Static member variable definition  
 Singleton* Singleton::mp_singleton = NULL;
  
 //*************************************************************************************
 // member function definition  -- GetInstance()
 // very first implementation which come and which is not 
 // a good implementation will looks like below -
 /*
 Singleton* Singleton::GetInstance()
 {
 //Lock lock;
 if(mp_singleton == NULL)
  mp_singleton = new Singleton;
 // release lock
return mp_singleton; } */ // what is the problem with above mentioned implementation ? // - First if threads are coming sequentially then first time it will lock and create // the pointer, but once it create singleton pointer for all other call it has to // go to else part and return the created pointer. unnecessary we will bear the // cost of lock and unlock else block though we have already created pointer. //************************************************************************************* // member function definition -- GetInstance() // Second most answered implementation is /* Singleton* Singleton::GetInstance() { if(mp_singleton == NULL){ //first time check //Lock lock; mp_singleton = new Singleton; // release lock } return mp_singleton; } */ // what is the problem with above mentioned implementation ? // - what if 2 threads come at same time in if condition and both went inside and // locked by synchronization variable? then once first thread create pointer // second thread will also create pointer as it is already inside of if block. // Then we will end up with two pointer though it supposed to have only one // as per singleton principle. //************************************************************************************* // member function definition -- GetInstance() // third most answered implementation is - Double-Checked Locking Pattern ( DCPL ) Singleton* Singleton::GetInstance() { if(mp_singleton == NULL){ //first time check //Lock lock; if(mp_singleton == NULL) // second time check mp_singleton = new Singleton; // release lock } return mp_singleton; } //************************************************************************************* //entry point int main(int argc, char ** argv) { Singleton *ptr1 = Singleton::GetInstance(); cout<<"Address of pointer one is - "<< &ptr1 <<endl; cout<<"Address of pointer Singleton pointer from pointer one is - "<< &(*ptr1) <<endl; Singleton *ptr2 = Singleton::GetInstance(); cout<<"Address of pointer Two is - "<< &ptr2 <<endl; cout<<"Address of pointer Singleton pointer from pointer two is - "<< &(*ptr2) <<endl; } /* ---------------------------------OutPut $ ./a.exe Address of pointer one is - 0x22caf8 Address of pointer Singleton pointer from pointer one is - 0x6000104c0 Address of pointer Two is - 0x22caf0 Address of pointer Singleton pointer from pointer two is - 0x6000104c0 */


Thanks for reading it. To read more on design patterns and basic design principles please see my web page. You can also join me on FB or on G++. Please drop comments for any question related to this blog.

Comments

Popular posts from this blog

Non-virtual interface idiom (NVI)

Architectural patterns => Mud to structure => layers.

Architectural style -> Adoptable system -> Reflection.