Wednesday, 28 June 2017

Singleton Design Pattern

Design patterns are classified in to three types:
  Design Pattern provides a solution to common problems which occur in software design.
  GoF (Gang of four) design pattern can be classified into three groups.
 
   1. Creational Design Pattern
   2. Structural Design Pattern
   3. Behavioral Design pattern.

1. Creational Design Pattern:
      -> Creational Patterns deals mainly with creation of Classes & Objects.
      - > It deal with creation of objects.
      -> How to create the objects efficiently.

2. Behavioral Design pattern:
     -> Behavioral Patterns deals with Class & Object communication.
     -> It deal with the objects interact each other
          -> How to interact or communicate with the objects efficiently.

3. Structural Design Pattern:
      -> Structural Patterns deals with Class & Object Composition.
      -> It deal with structure of objects.
            -> How objects are composed in other objects. With respect to inheritance, composition (IS_A or HAS_A relationships) etc.
          
Let's start discuss about Creational Design Pattern:

Creational Design pattern:
   1. Singleton Class.
  
Singleton Class:
   What is Singleton class?
     Singleton class means it has single instance of class (or only one object). You cannot create more than one object using singleton pattern.
  
   Why it is required?
      Still, there are times when an application needs a single instance of a given class and a global point of access to that class.
  
   How it is implemented in C++?
    Define a private static attribute in the "single instance" class.
    Define a public static accessor function in the class.
    Define all constructors to be protected or private.

    class singleton
    {
        private:
            //Declare the private constructor
             singleton()
             {
             }

             // Declare Static member Attribute or Instance
             static singleton *object;
        public:
            // Declare the static function
            static singleton *getInstance();

            void display();
};


//Initialize the static Member variable
singleton *singleton::object= NULL;

    Do "lazy initialization" (creation on first use) in the accessor function.
   
    //Global accessor function
    singleton *singleton::getInstance()
    {
       if(object == NULL)
       {
         object = new singleton();
       }
       return object;
    }


    Clients may only use the accessor function to manipulate the Singleton

    singleton::getInstance()->yourMethod();

     Inheritance of Singleton Class
     > Inheriting a singleton class should be prohibited.
     > Making a singleton class inheritable means any number of child classes can inherit from it creating multiple instances of the singleton class which will violate the principle of singletons.
      
    Overall :      
    1. Constructor should be private, if not planning for inheritance.
    2.  Copy Constructor should be made private, this way we enforce only one copy of the object.
            Singleton Obj2 = Obj1; // copy constructor gets called
    3. Assignment Operator should be made private, this way we enforce only one copy of the object.
            Singleton Obj3;
            Obj3 = Obj1;
    4. Destructor should be made private, so that it cannot be deleted.
       By making the above private, these methods cannot be invoked by the user. Thus, we avoid the multiple instance of the class.
           
What are the use cases for singleton class?
 The singleton pattern can be used for anything that you don't want to repeat.
 An example of a shared resource would be Logger, Print Spooler, etc.

You use a singleton when you need to manage a shared resource. For instance a printer spooler. Your application should only have a single instance of the spooler in order to avoid conflicting request for the same resource.   Or a database connection or a file manager etc.
  
Example 1 - Logger Classes
The Singleton pattern is used in the design of logger classes.
This classes are usually implemented as a singletons, and provides a global logging access point in all the application components without being necessary to create an object each time a logging operations is performed.
       
Example 2 - Configuration Classes
The Singleton pattern is used to design the classes which provides the configuration settings for an application.
By implementing configuration classes as Singleton not only that we provide a global access point, but we also keep the instance we use as a cache object.
When the class is instantiated( or when a value is read ) the singleton will keep the values in its internal structure. If the values are read from the database or from files this avoids the reloading the values each time the configuration parameters are used.

Example 3 - Accessing resources in shared mode
It can be used in the design of an application that needs to work with the serial port. Let's say that there are many classes in the application, working in an multi-threading environment, which needs to operate actions on the serial port. In this case a singleton with synchronized methods could be used to be used to manage all the operations on the serial port.

Example 1#

#include<iostream>
using namespace std;

class singleton
{
   private:
     //Declare the private constructor
     singleton()
     {
     }

     // Declare Static member Attribute or Instance
     static singleton *object;

   public:
     // Declare the static function
     static singleton *getInstance();

     void display();
};
//Initialize the static Member
singleton *singleton::object= NULL;


//Global accessor function
singleton *singleton::getInstance()
{
   if(object == NULL)
   {
     object = new singleton();
   }
   return object;
}

void singleton::display()
{
  cout<< "Base method is called";
}
// Main function
int main()
{
  singleton::getInstance()->display();

  return 0;
}


Output:
Base method is called
-> Do you think the above program is perfect singleton class, let me break this singleton behavior by creating another object using copy constructor.
  
// Main function
int main()
{
  singleton *ob1 = singleton::getInstance();
  singleton ob2(*ob1)
  singleton ob3 = ob2;
  return 0;
}

# Example 2:

#include<iostream>
using namespace std;
class singleton
{
   private:
     //Declare the private constructor
     singleton()
     {
     }
     // Declare Static memeber Attribute or Instace
     static singleton *object;
   public:
     // Declare the static function
     static singleton *getInstance();

     void display();
};
singleton *singleton :: object= NULL;
//Global accessor function
singleton *singleton::getInstance()
{
   if(!object)
   {
     object = new singleton();
   }
   return object;
}
void singleton::display()
{
  cout<< "Base method is called:\t"<<this<<endl;
}
// Main function
int main()
{
  singleton *p= singleton::getInstance();
  p->display();

  singleton ob(*p);

  ob.display();

  singleton ob3=ob;
  ob3.display();

  return 0;
}


Output:
Base method is called   0x8a5d008
Base method is called   0xbf84470a
Base method is called   0xbf84470b
------------------------------------------------------------------------------------------
HOW to SOLVE the above issue and MAKE as perfect singleton class.
------------------------------------------------------------------------------------------
#include<iostream>
using namespace std;

class singleton
{
   private:
     //Declare the private constructor
     singleton()
     {
     }

     // Declare Copy constructor
     singleton(const singleton&)
     {
     }

     // Declare Assignment Operator
     singleton operator=(const singleton&)
     {
     }

     // Destructor
     ~singleton()
     {
     }

     // Declare Static memeber Attribute or Instace
     static singleton *object;

     // Reference Count
     static int reference_count;
   public:
     // Declare the static function
     static singleton *getInstance();

     void release_memory();

     void display();
};

//Intialise the static members of the class
singleton *singleton :: object= NULL;
int singleton:: reference_count= 0;

//Global accessor function
singleton *singleton::getInstance()
{
   if(!object)
   {
     object = new singleton();
   }
   // Maintain Reference Count for Multiple threaded
   reference_count++;
   return object;
}
// Release memory
void singleton :: release_memory()
{
  // Release the instance
  reference_count--;

  if((!object) && (reference_count==0))
  {
    delete object;
    object=NULL;
  }
}

void singleton::display()
{
  cout<< "Base method is called \t"<<this<<endl;
}
// Main function
int main()
{
  singleton *p= singleton::getInstance();
  p->display();
  return 0;
}

------------------------------------------------------------------------------
ANOTHER BEST WAY TO AVOID MEMORY LEAKS as well
-------------------------------------------------------------------------------
#include<iostream>
using namespace std;

class singleton
{
   private:
     //Declare the private constructor
     singleton()
     {
     }
     // Declare Copy constructor
     singleton(const singleton&)
     {
     }

     // Declare Assignment Operator
     singleton operator=(const singleton&)
     {
     }

     // Destructor
     ~singleton()
     {
     }

     // Declare Static memeber Attribute or Instace
     static singleton *object;

   public:
     // Declare the static function
     static singleton &getInstance();

     void display();
};

//Intialise the static members of the class
singleton *singleton :: object= NULL;

//Global accessor function
singleton &singleton::getInstance()
{
   static singleton obj;
   object= &obj;
  
   return *object;
}

void singleton::display()
{
  cout<< "Base method is called \t"<<this<<endl;
}
// Main function
int main()
{
  singleton *p= &singleton::getInstance();
  p->display();
  return 0;
}

--------------------------------------------- 
Inheritance of the Singleton Class.
---------------------------------------------
You can only inherit singleton class only if the base constructor is either public or protected.
Thus, a base singleton class needs to make the constructor, destructor as protected.

#include<iostream>
using namespace std;

class singleton
{
   protected:
     //Declare the private constructor
     singleton()
     {
     }
     // Destructor
     ~singleton()
     {

     }
   private:
     // Declare Copy constructor
     singleton(const singleton&)
     {
     }

     // Declare Assignment Operator
     singleton &operator=(const singleton&)
     {
     }

     // Declare Static memeber Attribute or Instace
     static singleton *object;

   public:
     // Declare the static function
     static singleton &getInstance();

     void display();
};

//Intialise the static members of the class
singleton *singleton :: object= NULL;

//Global accessor function
singleton &singleton::getInstance()
{
   static singleton obj;
  
   object= &obj;
   return *object;
}

void singleton::display()
{
  cout<< "Base method is called \t"<<this<<endl;
}
// Derived Class
class derived:public singleton
{
};
// Main function
int main()
{
  singleton &p= singleton::getInstance();
  p.display();
 
  // or
  // singleton *p= &singleton::getInstance();
  // p->display();
 
  // or
  // singleton::getInstance().display();
  return 0;

  derived d1;
}

Notes:
   Reference in C++ , means it is an alias name of existing variable. int &p=i; It means p and i referencing to same memory location.   If i change the value of p and the same value shall be reflected to i.
      singleton &p= singleton::getInstance();  // It means p is referenced with the memory location of get instance.
  
   int &p; // Not allowed. It should be intialised as int i; int &p=i;  int &p=66 // Not allowed.
 With out virtual keyword: because there is no Upcasting ( Assign the derived class object address to the Base class pointer)
In this case, we don't require the virtual Keyword.

#include<iostream>
using namespace std;

class singleton
{
  protected:
     //Declare the private constructor
     singleton()
     {
     }
     // Destructor
     ~singleton()
     {
          cout<< "singleton Virtual Destrcutor is called"<<endl;
     }
   private:
     // Declare Copy constructor
     singleton(const singleton&)
     {
     }

     // Declare Assignment Operator
     singleton &operator=(const singleton&)
     {
     }

     // Declare Static memeber Attribute or Instace
     static singleton *object;

   public:
     // Declare the static function
     static singleton &getInstance();

};
// Derived class
class derived : public singleton
{
   public:
       derived(){}
       ~derived()
       {
          cout<< "Derived Virtual Destrcutor is called"<<endl;
       }

};
// Main function
int main()
{
  derived *p= new derived();    // No Upcasting
  delete p;
}


Output:
  Derived Virtual Destrcutor is called
  singleton Virtual Destrcutor is called
---------------------------------------------------------------------------------------------------------------------
Upcasting with out Virtual keyword:  -> I  intentionally put Destructor in Public to delete.. 
But try to avoid this...
---------------------------------------------------------------------------------------------------------------------
#include<iostream>
using namespace std;

class singleton
{
  protected:
     //Declare the private constructor
     singleton()
     {
     }
   private:
     // Declare Copy constructor
     singleton(const singleton&)
     {
     }
     // Declare Assignment Operator
     singleton &operator=(const singleton&)
     {
     }
     // Declare Static member Attribute or Instance
     static singleton *object;

   public:
     // Declare the static function
     static singleton &getInstance();
     // Destructor
     ~singleton()
     {
          cout<< "singleton Virtual Destrcutor is called"<<endl;
     }
};

//Intialise the static members of the class
singleton *singleton :: object= NULL;

// Derived class
class derived : public singleton
{
   public:
       derived(){}
       ~derived()
       {
          cout<< "Derived Virtual Destrcutor is called"<<endl;
       }

};
// Main function
int main()
{
  singleton *p= new derived();   //UPCASTING
  delete p;
}


Output:
singleton Virtual Destrcutor is called    -> Always the base class destructor is called.
Notes: Singleton class destrcutor is private.

--------------------------------------------------------------------------
With virtual Keyword and Upcasting -> The output is proper
--------------------------------------------------------------------------
#include<iostream>
using namespace std;

class singleton
{
  protected:
     //Declare the private constructor
     singleton()
     {
     }
   private:
     // Declare Copy constructor
     singleton(const singleton&)
     {
     }

     // Declare Assignment Operator
     singleton &operator=(const singleton&)
     {
     }

     // Declare Static memeber Attribute or Instace
     static singleton *object;

   public:
     // Declare the static function
     static singleton &getInstance();
     // Destructor
     virtual ~singleton()
     {
          cout<< "singleton Virtual Destrcutor is called"<<endl;
     }

};

//Intialise the static members of the class
singleton *singleton :: object= NULL;

// Derived class
class derived : public singleton
{
    public:
       derived(){}
       virtual ~derived()
       {
          cout<< "Derived Virtual Destrcutor is called"<<endl;
       }

};

// Main function
int main()
{
  singleton *p= new derived();
  delete p;
}

Output:
Derived Virtual Destructor is called
singleton Virtual Destructor is called


------------------------------------------------------------------------------------  
Use Smart Pointers in the singleton class to avoid the memory Leaks:
-------------------------------------------------------------------------------------
#include<iostream>
#include<memory>
using namespace std;
class Singleton
{
public:
    static auto_ptr<Singleton> getObj();   //get the object of Singleton class
    void func1();
    ~Singleton(void);
protected:
    Singleton(void);               //constructor in protected for inheritance
    static auto_ptr<Singleton> my_Obj;
 

};

auto_ptr<Singleton> Singleton::getObj()
{
    if(my_Obj.get() == NULL)
    {
        auto_ptr<Singleton> temp1(new Singleton);
        my_Obj = temp1;
    }
    else
    {
        cout<<"only can create one object"<<endl;
    }
    return my_Obj;
}


-------------------------------------
Problems of Singleton Pattern
-------------------------------------
One cannot mock the singleton class and pass it.
The reason is that the singleton pattern prohibits – copy constructor and assignment operator. So, there is no way to do the unit-testing here.


2 comments:

  1. Singletons are very often misused, to the point that they are almost considered an "anti-pattern":
    https://www.infoworld.com/article/3112025/application-development/design-patterns-that-i-often-avoid-singleton.html

    ReplyDelete
  2. Pemahaman akan permainan menjadi kunci utama yang sangat penting sekali untuk dikuasai jika anda memang benar-benar ingin mendapatkan kemenangan dan sukses kedepannya dalam permainan tersebut.
    asikqq
    http://dewaqqq.club/
    http://sumoqq.today/
    interqq
    pionpoker
    bandar ceme
    freebet tanpa deposit
    paito warna terlengkap
    syair sgp

    ReplyDelete