//---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 //+------------------------------------------------------------------+