[r5]: / Tags / The -Decorator- Pattern / Decorator_Application2.project  Maximize  Restore  History

Download this file

481 lines (376 with data), 700.6 kB

-------------------------------------------------------------------------------
getDescription
-------------------------------------------------------------------------------

                      Illustrative method of the pattern


METHOD getDescription: string

-------------------------------------------------------------------------------
getValue
-------------------------------------------------------------------------------

                      Ilustrative method of the pattern


METHOD getValue: REAL

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


PROGRAM PLC_PRG

VAR
    basicComponent: ConcreteComponent;
    iTempDisplay: INT;
    rDisplayValue: REAL;
    sDisplayDescription: string;
    ptrDecorA: pointer;
    ptrDecorB: pointer;
    ptrDecorC: pointer;
    bDecorA: BOOL;
    bDecorB: BOOL;
    bDecorC: BOOL;
END_VAR
//The visualization element will handle the request from the client in real time.
//The client can chose any possible combination for the element and the display will show the specific results.

//As there are 3 possible options, the programs checks a 3X3 matrix and checks the last handled request

//If the user has not chosen any Decoration AND iTempDisplay is different to the initial state of 1,
IF NOT bDecorA AND NOT bDecorB AND NOT bDecorC AND iTempDisplay <> 1 //000
	THEN
	//Then the request from the client is just a basic component, 
	// so from the basic component declared on the PLC_PRG declaration part the program delivers the results
	
	//The temporal Value field gets the actual value of the request from the basicComponent object
	rDisplayValue := basicComponent.getValue();
	//The temporal Description field gets the actual value of the request from the basicComponent object
	sDisplayDescription := basicComponent.getDescription();
	//The temporal state of the display is set to 1, this will avoid processing duplicate requests
	iTempDisplay := 1;
END_IF

//If the user has chosen only Decoration A AND iTempDisplay is different to this concrete state of 2,
IF bDecorA AND NOT bDecorB AND NOT bDecorC AND iTempDisplay <> 2 //100
	THEN
	//Then the request from the client is a basic component with Decoration A, 
	// so from the basic component declared on the PLC_PRG declaration part the program delivers the results
	
	//First a ConcreteDecoratorA object must be created passing as an argument the basicComponent object
	ptrDecorA := __NEW(ConcreteDecoratorA(tempInputComponent := basicComponent));
	//The temporal Value field gets the actual value of the request from the ConcreteDecoratorA object
	rDisplayValue := ptrDecorA^.getValue();
	//The temporal Description field gets the actual value of the request from the ConcreteDecoratorA object
	sDisplayDescription := ptrDecorA^.getDescription();
	//The temporal state of the display is set to 2, this will avoid processing duplicate requests
	iTempDisplay := 2;
	//Now the ConcreteDecoratorA object is destroyed to free memory
	__DELETE(ptrDecorA);
END_IF

//If the user has chosen Decorations A and B AND iTempDisplay is different to this concrete state of 3,
IF bDecorA AND bDecorB AND NOT bDecorC AND iTempDisplay <> 3 //110
	THEN
	//Then the request from the client is just a basic component, 
	// so from the basic component declared on the PLC_PRG declaration part the program delivers the results
	
	//First a ConcreteDecoratorA object must be created passing as an argument the basicComponent object
	ptrDecorA := __NEW(ConcreteDecoratorA(tempInputComponent := basicComponent));
	//Then a ConcreteDecoratorB object must be created passing as an argument the ConcreteDecoratorA object
	ptrDecorB := __NEW(ConcreteDecoratorB(tempInputComponent := ptrDecorA^));
	//The temporal Value field gets the actual value of the request from the ConcreteDecoratorB object
	rDisplayValue := ptrDecorB^.getValue();
	//The temporal Description field gets the actual value of the request from the ConcreteDecoratorB object
	sDisplayDescription := ptrDecorB^.getDescription();
	//The temporal state of the display is set to 3, this will avoid processing duplicate requests
	iTempDisplay := 3;
	//Now the ConcreteDecoratorA object is destroyed to free memory
	__DELETE(ptrDecorA);
	//Now the ConcreteDecoratorB object is destroyed to free memory
	__DELETE(ptrDecorB);
END_IF

//If the user has chosen Decorations A, B and C AND iTempDisplay is different to this concrete state of 4,
IF bDecorA AND bDecorB AND bDecorC AND iTempDisplay <> 4 //111
	THEN
	//Then the request from the client is just a basic component, 
	// so from the basic component declared on the PLC_PRG declaration part the program delivers the results
	
	//First a ConcreteDecoratorA object must be created passing as an argument the basicComponent object
	ptrDecorA := __NEW(ConcreteDecoratorA(tempInputComponent := basicComponent));
	//Then a ConcreteDecoratorB object must be created passing as an argument the ConcreteDecoratorA object
	ptrDecorB := __NEW(ConcreteDecoratorB(tempInputComponent := ptrDecorA^));
	//Then a ConcreteDecoratorC object must be created passing as an argument the ConcreteDecoratorB object
	ptrDecorC := __NEW(ConcreteDecoratorC(tempInputComponent := ptrDecorB^));
	//The temporal Value field gets the actual value of the request from the ConcreteDecoratorC object
	rDisplayValue := ptrDecorC^.getValue();
	//The temporal Description field gets the actual value of the request from the ConcreteDecoratorC object
	sDisplayDescription := ptrDecorC^.getDescription();
	//The temporal state of the display is set to 4, this will avoid processing duplicate requests
	iTempDisplay := 4;
	//Now the ConcreteDecoratorA object is destroyed to free memory
	__DELETE(ptrDecorA);
	//Now the ConcreteDecoratorB object is destroyed to free memory
	__DELETE(ptrDecorB);
	//Now the ConcreteDecoratorC object is destroyed to free memory
	__DELETE(ptrDecorC);
END_IF

//If the user has chosen Decorations A and C AND iTempDisplay is different to this concrete state of 2,
IF bDecorA AND NOT bDecorB AND bDecorC AND iTempDisplay <> 5 //101
	THEN
	//Then the request from the client is just a basic component, 
	// so from the basic component declared on the PLC_PRG declaration part the program delivers the results
	
	//First a ConcreteDecoratorA object must be created passing as an argument the basicComponent object
	ptrDecorA := __NEW(ConcreteDecoratorA(tempInputComponent := basicComponent));
	//Then a ConcreteDecoratorC object must be created passing as an argument the ConcreteDecoratorA object
	ptrDecorC := __NEW(ConcreteDecoratorC(tempInputComponent := ptrDecorA^));
	//The temporal Value field gets the actual value of the request from the ConcreteDecoratorC object
	rDisplayValue := ptrDecorC^.getValue();
	//The temporal Description field gets the actual value of the request from the ConcreteDecoratorC object
	sDisplayDescription := ptrDecorC^.getDescription();
	//The temporal state of the display is set to 5, this will avoid processing duplicate requests
	iTempDisplay := 5;
	//Now the ConcreteDecoratorA object is destroyed to free memory
	__DELETE(ptrDecorA);
	//Now the ConcreteDecoratorC object is destroyed to free memory
	__DELETE(ptrDecorC);
END_IF

//If the user has chosen only Decoration B AND iTempDisplay is different to this concrete state of 6,
IF NOT bDecorA AND bDecorB AND NOT bDecorC AND iTempDisplay <> 6 //010
	THEN
	//Then the request from the client is just a basic component, 
	// so from the basic component declared on the PLC_PRG declaration part the program delivers the results
	
	//First a ConcreteDecoratorB object must be created passing as an argument the basicComponent object
	ptrDecorB := __NEW(ConcreteDecoratorB(tempInputComponent := basicComponent));
	//The temporal Value field gets the actual value of the request from the ConcreteDecoratorB object
	rDisplayValue := ptrDecorB^.getValue();
	//The temporal Description field gets the actual value of the request from the ConcreteDecoratorB object
	sDisplayDescription := ptrDecorB^.getDescription();
	//The temporal state of the display is set to 6, this will avoid processing duplicate requests
	iTempDisplay := 6;
	//Now the ConcreteDecoratorB object is destroyed to free memory
	__DELETE(ptrDecorB);
END_IF

//If the user has chosen Decorations B and C AND iTempDisplay is different to this concrete state of 7,
IF NOT bDecorA AND bDecorB AND bDecorC AND iTempDisplay <> 7 //011
	THEN
	//Then the request from the client is just a basic component, 
	// so from the basic component declared on the PLC_PRG declaration part the program delivers the results
	
	//First a ConcreteDecoratorB object must be created passing as an argument the basicComponent object
	ptrDecorB := __NEW(ConcreteDecoratorB(tempInputComponent := basicComponent));
	//Then a ConcreteDecoratorC object must be created passing as an argument the ConcreteDecoratorB object
	ptrDecorC := __NEW(ConcreteDecoratorC(tempInputComponent := ptrDecorB^));
	//The temporal Value field gets the actual value of the request from the ConcreteDecoratorC object
	rDisplayValue := ptrDecorC^.getValue();
	//The temporal Description field gets the actual value of the request from the ConcreteDecoratorC object
	sDisplayDescription := ptrDecorC^.getDescription();
	//The temporal state of the display is set to 7, this will avoid processing duplicate requests
	iTempDisplay := 7;
	//Now the ConcreteDecoratorB object is destroyed to free memory
	__DELETE(ptrDecorB);
	//Now the ConcreteDecoratorC object is destroyed to free memory
	__DELETE(ptrDecorC);
END_IF

//If the user has chosen only Decoration C AND iTempDisplay is different to this concrete state of 8,
IF NOT bDecorA AND NOT bDecorB AND bDecorC AND iTempDisplay <> 8 //001
	THEN
	//Then the request from the client is just a basic component, 
	// so from the basic component declared on the PLC_PRG declaration part the program delivers the results
	
	//First a ConcreteDecoratorC object must be created passing as an argument the basicComponent object
	ptrDecorC := __NEW(ConcreteDecoratorC(tempInputComponent := basicComponent));
	//The temporal Value field gets the actual value of the request from the ConcreteDecoratorC object
	rDisplayValue := ptrDecorC^.getValue();
	//The temporal Description field gets the actual value of the request from the ConcreteDecoratorC object
	sDisplayDescription := ptrDecorC^.getDescription();
	//The temporal state of the display is set to 8, this will avoid processing duplicate requests
	iTempDisplay := 8;
	//Now the ConcreteDecoratorC object is destroyed to free memory
	__DELETE(ptrDecorC);
END_IF
-------------------------------------------------------------------------------
ConcreteComponent
-------------------------------------------------------------------------------

                  This class creates the most basic object well called. This object is to be decorated


FUNCTION_BLOCK ConcreteComponent

VAR
    sDescription: string;
    rValue: REAL;
END_VAR

-------------------------------------------------------------------------------
getDescription
-------------------------------------------------------------------------------

                        Illustrative method of the pattern


METHOD getDescription: string
//Description of the plain object is given
getDescription := This^.sDescription;
-------------------------------------------------------------------------------
getValue
-------------------------------------------------------------------------------

                        Illustrative method of the pattern


METHOD getValue: REAL
//Assume we are going to calculate the cost os the object.
//The plain value (without extra decoration) is given
getValue := THIS^.rValue;
-------------------------------------------------------------------------------
fb_init
-------------------------------------------------------------------------------


METHOD fb_init: 

VAR_INPUT
    bInitRetains: BOOL;
    bInCopyCode: BOOL;
END_VAR
//Sets the default description for the objects of this class
THIS^.sDescription := 'Plain Component';
//Sets the default value for the objects of this class
THIS^.rValue := 4.0;
-------------------------------------------------------------------------------
Decorator
-------------------------------------------------------------------------------

                  This class mainteins the reference to a ConcreteComponent object and works as an interface 
 for its subclasses to decorate the ConcreteComponent 


FUNCTION_BLOCK Decorator

VAR
    tempComponent: Component_Interface;
    sDescription: string;
    rValue: REAL;
END_VAR

-------------------------------------------------------------------------------
getDescription
-------------------------------------------------------------------------------

                        Illustrative method of the pattern


METHOD getDescription: string
//Outputs the description of the component to be decorated tempComponent. If tempComponent is not an undecorated component (plain object)
// it means the program has to do at least 2 decorations. Then is going to output the previous decoration complete description
// to be used by the next decorator.
getDescription := THIS^.tempComponent.getDescription();
-------------------------------------------------------------------------------
getValue
-------------------------------------------------------------------------------

                        Illustrative method of the pattern


METHOD getValue: REAL
//Outputs the cost of the component to be decorated tempComponent. If tempComponent is not an undecorated component (plain object)
// it means the program has to do at least 2 decorations. Then is going to output the previous decoration complete value
// to be used by the next decorator.
getValue := tempComponent.getValue();
-------------------------------------------------------------------------------
fb_init
-------------------------------------------------------------------------------

                        Constructor of the decorator class called at instanciation


METHOD fb_init: 

VAR_INPUT
    bInitRetains: BOOL;
    bInCopyCode: BOOL;
    tempInputComponent: Component_Interface;
END_VAR
//This constructor stores the component to be decorated in its field tempComponent in orer to be used by all its subclasses
THIS^.tempComponent := tempInputComponent;

-------------------------------------------------------------------------------
ConcreteDecoratorA
-------------------------------------------------------------------------------

                  This class acts as a decorating class. It adds responsibilities and functionality to the component


FUNCTION_BLOCK ConcreteDecoratorA EXTENDS Decorator

VAR_INPUT
    tempInputComponent: Component_Interface;
END_VAR

-------------------------------------------------------------------------------
getDescription
-------------------------------------------------------------------------------

                        Illustrative method of the pattern


METHOD getDescription: string
//Outputs the decorated description of the component by obtaining the description of the component
// to be decorated stored in tempComponet.getDescription() and then concatenates the decoration
// description( ' Decorator A' as example)
getDescription :=CONCAT(THIS^.tempComponent.getDescription() , THIS^.sDescription);

-------------------------------------------------------------------------------
getValue
-------------------------------------------------------------------------------

                        Illustrative method of the pattern


METHOD getValue: REAL
//Outputs the decorated cost of the component by obtaining the cost of the component to be decorated 
// stored in tempComponent.getValue() and then adds the decoration value (0.5 as example)
getValue := tempComponent.getValue() + THIS^.rValue;
-------------------------------------------------------------------------------
fb_init
-------------------------------------------------------------------------------

                        Constructor of the decorating class called at instanciation


METHOD fb_init: 

VAR_INPUT
    bInitRetains: BOOL;
    bInCopyCode: BOOL;
    tempInputComponent: Component_Interface;
END_VAR
//Calls the constructor (fb_init) in its SUPER class (Decorator)
// in order to pass the component to be decorated to the Decorator constructor.
SUPER^.fb_init(TRUE, TRUE, tempInputComponent);
//Sets the default description for the objects of this class
THIS^.sDescription := ' Decorator A';
//Sets the default value for the objects of this class
THIS^.rValue := 0.5;
-------------------------------------------------------------------------------
ConcreteDecoratorB
-------------------------------------------------------------------------------

                  This class acts as a decorating class. It adds responsibilities and functionality to the component


FUNCTION_BLOCK ConcreteDecoratorB EXTENDS Decorator

VAR_INPUT
    tempInputComponent: Component_Interface;
END_VAR

-------------------------------------------------------------------------------
getDescription
-------------------------------------------------------------------------------

                        Illustrative method of the pattern


METHOD getDescription: string
//Outputs the decorated description of the component by obtaining the description of the component
// to be decorated stored in tempComponet.getDescription() and then concatenates the decoration
// description( ' Decorator B' as example)
getDescription :=CONCAT(THIS^.tempComponent.getDescription() , THIS^.sDescription);
-------------------------------------------------------------------------------
getValue
-------------------------------------------------------------------------------

                        Illustrative method of the pattern


METHOD getValue: REAL
//Outputs the decorated cost of the component by obtaining the cost of the component to be decorated 
// stored in tempComponent.getValue() and then adds the decoration value (0.35 as example)
getValue := tempComponent.getValue() + THIS^.rValue;
-------------------------------------------------------------------------------
fb_init
-------------------------------------------------------------------------------

                        Constructor of the decorating class called at instanciation


METHOD fb_init: 

VAR_INPUT
    bInitRetains: BOOL;
    bInCopyCode: BOOL;
    tempInputComponent: Component_Interface;
END_VAR
//Calls the constructor (fb_init) in its SUPER class (Decorator)
// in order to pass the component to be decorated to the Decorator constructor.
SUPER^.fb_init(TRUE, TRUE, tempInputComponent);
//Sets the default description for the objects of this class
THIS^.sDescription := ' Decorator B';
//Sets the default value for the objects of this class
THIS^.rValue := 0.35;
-------------------------------------------------------------------------------
ConcreteDecoratorC
-------------------------------------------------------------------------------

                  This class acts as a decorating class. It adds responsibilities and functionality to the component


FUNCTION_BLOCK ConcreteDecoratorC EXTENDS Decorator

VAR_INPUT
    tempInputComponent: Component_Interface;
END_VAR

-------------------------------------------------------------------------------
getValue
-------------------------------------------------------------------------------

                        Ilustrative method of the pattern


METHOD getValue: REAL
//Outputs the decorated cost of the component by obtaining the cost of the component to be decorated 
// stored in tempComponent.getValue() and then adds the decoration value (0.15 as example)
getValue := tempComponent.getValue() + THIS^.rValue;
-------------------------------------------------------------------------------
getDescription
-------------------------------------------------------------------------------

                        Illustrative method of the pattern


METHOD getDescription: string
//Outputs the decorated description of the component by obtaining the description of the component
// to be decorated stored in tempComponet.getDescription() and then concatenates the decoration
// description( ' Decorator C' as example)
getDescription :=CONCAT(THIS^.tempComponent.getDescription() , THIS^.sDescription);
-------------------------------------------------------------------------------
fb_init
-------------------------------------------------------------------------------

                        Constructor of the decorator class called at instanciation


METHOD fb_init: 

VAR_INPUT
    bInitRetains: BOOL;
    bInCopyCode: BOOL;
    tempInputComponent: Component_Interface;
END_VAR
//Calls the constructor (fb_init) in its SUPER class (Decorator)
// in order to pass the component to be decorated to the Decorator constructor.
SUPER^.fb_init(TRUE, TRUE, tempInputComponent);
//Sets the default description for the objects of this class
THIS^.sDescription := ' Decorator C';
//Sets the default value for the objects of this class
THIS^.rValue := 0.15;