Singleton – creational design pattern – library MetaTrader 5

//---singleton--------------------------------------------------------
//   creational design pattern
//   ---intent
//      ensure one instance of a class with a global point of access
//   ---benefits
//      the sole instance of a class may vary
//   ---applicability-------------------------------------------------
//      one instance of a class
//         accessible to clients from a well-known access point
//         extensible by subclassing
//            extended instance should be good without changing the code
//   ---structure
//                          |       singleton       |
//                          |-----------------------|
//                          |static instance()      |
//                          | return uniqueinstance |
//                          |singletonoperation()   |
//                          |getsingletondata()     |
//                          |-----------------------|
//                          |static uniqueinstance  |
//                          |singletondata          |
//
#include <SRCPatternsPatterns.mqh>
namespace Singleton
{
//---participants-----------------------------------------------------
class Singleton
//   instance method
//      lets clients access its unique instance
//      class operation
//         static member function in c++
//   own unique instance may be created
  {
public:
   static Singleton* Instance();
   void              SingletonOperation();
   string            GetSingletonData();
protected:
                     Singleton();
   static Singleton* uniqueInstance;
   string            singletonData;
  };
Singleton::Singleton(void) {} //constructor
Singleton* Singleton::uniqueInstance=NULL; //static member
void Singleton::SingletonOperation(void) //operation
  {
   Print("Setting singleton data");
   singletonData="Singleton data";
  }
string Singleton::GetSingletonData(void) //get data
  {
   Print("Reading singleton data");
   return singletonData;
  }
Singleton* Singleton::Instance(void) //get instance
  {
   if(!CheckPointer(uniqueInstance))
      uniqueInstance=new Singleton;
   return uniqueInstance;
  }
//---participants-----------------------------------------------------
class Client:public ClientExample
  {
public:
   string            Output();
   void              Run();
  };
string Client::Output() {return __FUNCTION__;}
//---collaborations---------------------------------------------------
void Client::Run() //clients access a singleton solely through instance()
  {
   Singleton* instance1=Singleton::Instance();
   Singleton* instance2=Singleton::Instance();
   string compareInstances=(instance1==instance2)?
                           "Instances are the same objects":
                           "Instances are different objects";
   Print(compareInstances);
//---
   instance1.SingletonOperation();
   string singletonData=instance2.GetSingletonData();
   Print(singletonData);
//---
   delete instance1;
  }
}
//---output-----------------------------------------------------------
//   creational::singleton::client::output
//   instances are the same objects
//   setting singleton data
//   reading singleton data
//   singleton data
//---consequences-----------------------------------------------------
//   ---controlled access to sole instance
//   ---reduced name space
//      better than global variables
//   ---operations and representation
//      can be changed
//      may be subclassed
//   ---variable number of instances is ok
//   ---static methods
//      more flexible than class operations
//      but non-virtual and non-polymorphic
//---implementation---------------------------------------------------
//   ---ensuring a unique instance
//      in c++
//         static member _instance
//            pointer to its unique instance
//         static instance()
//            lazy initialization 
//               create and store on first access
//            singleton subclass pointer to _instance can be assigned
//         constructor is protected
//   ---subclassing the singleton
//      singleton is determined in instance()
//         possible singletons are hard-wired
//      instance() implementation
//         in subclass, not in parent class
//            choice of singletons at link-time is fixed
//      registry of singletons
//         register themselves by name in constructor
//            static singleton is defined in the implementation file
//            all possible singletons must be created
//               else they won't get registered
//         map between string names and singletons
//         instance() asks for the singleton by name
//         looks up the singleton
//         returns if it exists
//---related patterns-------------------------------------------------
//   abstract factory, builder, prototype 
//      can be implemented using the singleton
//+------------------------------------------------------------------+
   
    📈 ROBOTFX MetaTrader Expert Advisors and Indicators to maximize profits and minimize the risks