[r5]: / Tags / The -Singleton- Pattern / Singleton_Application.project  Maximize  Restore  History

Download this file

146 lines (104 with data), 692.0 kB

VAR_GLOBAL
END_VAR

-------------------------------------------------------------------------------
Set_Background
-------------------------------------------------------------------------------

                      Illustrative method of the pattern


METHOD Set_Background: 

VAR_INPUT
    newBackground: DWORD;
END_VAR

-------------------------------------------------------------------------------
PLC_PRG
-------------------------------------------------------------------------------


PROGRAM PLC_PRG

VAR
    dwBlue: DWORD;
    dwGreen: DWORD;
    dwYellow: DWORD;
    instance1: ProxyToSingleton;
    instance2: ProxyToSingleton;
    instance3: ProxyToSingleton;
END_VAR
//The PLC_PRG handles the instanciation of the possible background colours and the ProxyToSingleton instances in order to be used by the Visualization element.
//The viasualization element (The client) handles the request for background change on the RealSingleton object through the ProxyToSinlgeton instances.
//These request are first processed by the ProxyToSingleton object and then passed to the one and only RealSingleton instance.
//The default background colour of the RealSingleton object is 'Blue' 

-------------------------------------------------------------------------------
RealSingleton
-------------------------------------------------------------------------------

                  This class is called RealSingleton because it works as singleton.  
As long as we only instanciate ProxyToSingleton objects, this class will work as a Singleton class should work.
The global access point to this class is the field .realSingleton^ in every ProxyToSingleton object.


FUNCTION_BLOCK RealSingleton

VAR
    backgroundColour: DWORD;
END_VAR

-------------------------------------------------------------------------------
fb_init
-------------------------------------------------------------------------------


METHOD fb_init: 

VAR_INPUT
    bInitRetains: BOOL;
    bInCopyCode: BOOL;
END_VAR
//The default valur for the background is set
THIS^.Set_Background(PLC_PRG.dwBlue);

-------------------------------------------------------------------------------
Set_Background
-------------------------------------------------------------------------------

                        Illustrative method of the pattern


METHOD Set_Background: 

VAR_INPUT
    newBackground: DWORD;
END_VAR
//Writes the backgroundColour field to the passed newBackground value
THIS^.backgroundColour := newBackground;
-------------------------------------------------------------------------------
ProxyToSingleton
-------------------------------------------------------------------------------

                  This class is called ProxyToSingleton because it works as a Proxy of the Singleton class. It handles the creation and instanciation of the 
 RealSingleton class. Something like the proper static method GetInstance(); in any singleton pattern.
So the ProxyToSingleton class has a static Singleton object as a field and whenever we instanciate a 
 ProxyToSingleton object we will have the RealSingleton object as its static field .realSingleton^


FUNCTION_BLOCK ProxyToSingleton

VAR_GLOBAL
    bFirstInstance: BOOL;
    realSingleton: pointer;
END_VAR

-------------------------------------------------------------------------------
fb_init
-------------------------------------------------------------------------------


METHOD fb_init: 

VAR_INPUT
    bInitRetains: BOOL;
    bInCopyCode: BOOL;
END_VAR
//THIS FUNCTION WORKS AS THE CONSTRUCTOR OF THE ProxyToSingleton CLASS
// It handles the creation of the only RealSingleton object. It uses the concept of lazy instanciation.

//If the static property .bFirstInstance is TRUE
IF THIS^.bFirstInstance = TRUE
	
THEN
		//There is already a Singleton object.
		//So we don't have to do anything, this new ProxyToSingleton object will already have the address of the 
		// RealSingleton object in its pointer .realSingleton
	
	ELSE	//If the static property .bFirstInstance is FALSE
	
		//There is not a Singleton object so the ProxyToSingleton object calling the constructor 
		// should create the RealSingleton object in its pointer field .realSingleton 
		//Then we change the status of the static variable bFirstInstance to TRUE and avoid overwriting the realSingleton address.
		//If the Singleton object is destroyed, .bFirstInstance should be set to FALSE again.
		THIS^.bFirstInstance := TRUE;
		
		//Reference the value of the first RealSingleton instance to the FakeSingleton object to save 
		// the address of the real Singleton instance.
		THIS^.realSingleton := __NEW(RealSingleton);
END_IF
-------------------------------------------------------------------------------
Set_Background
-------------------------------------------------------------------------------

                        Illustrative method of the pattern


METHOD Set_Background: 

VAR_INPUT
    newBackground: DWORD;
END_VAR
//The ProxyToSingleton object handles the request and send the appropiate reques to the one and only RealSingleton instance
THIS^.realSingleton^.Set_Background(newBackground);