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);