[r5]: / Tags / The -Builder- Pattern / Builder_Application RPi.project  Maximize  Restore  History

Download this file

391 lines (296 with data), 698.4 kB

-------------------------------------------------------------------------------
Set_Part1
-------------------------------------------------------------------------------

                      Illustrative method of the pattern to set the part1


METHOD Set_Part1: 

VAR_INPUT
    part1: string;
END_VAR

-------------------------------------------------------------------------------
Set_Part2
-------------------------------------------------------------------------------

                      Illustrative method of the pattern to set the part2


METHOD Set_Part2: 

VAR_INPUT
    part2: string;
END_VAR

-------------------------------------------------------------------------------
Set_Part3
-------------------------------------------------------------------------------

                      Illustrative method of the pattern to set the part3


METHOD Set_Part3: 

VAR_INPUT
    part3: string;
END_VAR

-------------------------------------------------------------------------------
Set_Main_Part
-------------------------------------------------------------------------------

                      Illustrative method of the pattern to set the main part


METHOD Set_Main_Part: 

VAR_INPUT
    mainPart: string;
END_VAR

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


PROGRAM PLC_PRG

VAR
    specsBuilder1: ARRAY [..] OF ;
    specsBuilder2: ARRAY [..] OF ;
    specsBuilder3: ARRAY [..] OF ;
    tableArray: ARRAY [..] OF ;
    sMessageLog: string;
    bRequest: BOOL;
    bRow: BOOL;
    iRow: INT;
    prod: pointer;
    concreteBuilder1: ConcreteBuilder;
    concreteBuilder2: ConcreteBuilder;
    concreteBuilder3: ConcreteBuilder;
    aDirector: Director;
END_VAR
//The visualization element lets the client chose an option blueprint to build a Car
//Once the client has chosen his prefered option, he can then procede to make the request of construction.
//The bottom rectangle will handle all possible responses from te application to the client.

//If the client makes a request in the visualization element
IF bRequest
	THEN
	//CASE instruction to handle all possible cases of the cleint's request
	//The value to verify is iRow to specify which row the client has chosen
	CASE iRow OF
		//If the client has chosen the "Title" row from the visualization element we notify the client to chose a Car blueprint
		0: 	sMessageLog := 'You must first select a Car to make a request. Waiting for your request';
			//Once this reques has been handled, the reques flag is set to FALSE
			bRequest := FALSE;
		
		//If the client has chosen the first option row, the builder notifies the client about the received request
		1:	sMessageLog := 'Your red car is being built';
			//A new product object is created on demand
			prod := __NEW(Product);
			//The directo object receives the ConcreteBuilder object to be used based on the clients choice
			aDirector(inputConcreteBuilder := concreteBuilder1);
			//The Product object request the construction to the Director.
			prod^ := aDirector.Construct();
			//The Builder's response after the Director object has handled the proper request
			sMessageLog := CONCAT( 'Your car has been built. It has ' , prod^.toString());
			//Once this reques has been handled, the reques flag is set to FALSE
			bRequest := FALSE;
			//Once this reques has been handled, the Product object is deleted to free memory
			__DELETE(prod);
			
		//If the client has chosen the second option row, the builder notifies the client about the received request	
		2:	sMessageLog := 'Your black car is being built';
			//A new product object is created on demand
			prod := __NEW(Product);
			//The directo object receives the ConcreteBuilder object to be used based on the clients choice
			aDirector(inputConcreteBuilder := concreteBuilder2);
			//The Product object request the construction to the Director.
			prod^ := aDirector.Construct();
			//The Builder's response after the Director object has handled the proper request
			sMessageLog := CONCAT( 'Your car has been built. It has ' , prod^.toString());
			//Once this reques has been handled, the reques flag is set to FALSE
			bRequest := FALSE;
			//Once this reques has been handled, the Product object is deleted to free memory
			__DELETE(prod);
			
		//If the client has chosen the third option row, the builder notifies the client about the received request	
		3: sMessageLog := 'Your white car is being built';
			//A new product object is created on demand
			prod := __NEW(Product);
			//The directo object receives the ConcreteBuilder object to be used based on the clients choice
			aDirector(inputConcreteBuilder := concreteBuilder3);
			//The Product object request the construction to the Director.
			prod^ := aDirector.Construct();
			//The Builder's response after the Director object has handled the proper request
			sMessageLog := CONCAT( 'Your car has been built. It has ' , prod^.toString());
			//Once this reques has been handled, the reques flag is set to FALSE
			bRequest := FALSE;
			//Once this reques has been handled, the Product object is deleted to free memory
			__DELETE(prod);
			
		//If the client makes any unrecognized request.	
		ELSE
			sMessageLog := 'That is not a valir selection. Waiting for your request';
			//Once this reques has been handled, the reques flag is set to FALSE
			bRequest := FALSE;

	END_CASE
END_IF
-------------------------------------------------------------------------------
ConcreteBuilder
-------------------------------------------------------------------------------

                  This is the concrete builder class, reponsible for building the final product object


FUNCTION_BLOCK ConcreteBuilder

VAR
    localProduct: Product;
    specifications: ARRAY [..] OF ;
END_VAR

-------------------------------------------------------------------------------
Set_Main_Part
-------------------------------------------------------------------------------

                        Illustrative method of the pattern to set the main part


METHOD Set_Main_Part: 

VAR_INPUT
    mainPart: string;
END_VAR
//Sets the passed value to its corresponding field. 
//We can say that the the final product is in process of being built.
//So this is a step into building the final product done by the builder.
THIS^.localProduct.mainPart := mainPart;


-------------------------------------------------------------------------------
Set_Part1
-------------------------------------------------------------------------------

                        Illustrative method of the pattern to set the part1


METHOD Set_Part1: 

VAR_INPUT
    part1: string;
END_VAR
//Sets the passed value to its corresponding field. 
//We can say that the the final product is in process of being built.
//So this is a step into building the final product done by the builder.
THIS^.localProduct.part1 := part1;
-------------------------------------------------------------------------------
Set_Part2
-------------------------------------------------------------------------------

                        Illustrative method of the pattern to set the part2


METHOD Set_Part2: 

VAR_INPUT
    part2: string;
END_VAR
//Sets the passed value to its corresponding field. 
//We can say that the the final product is in process of being built.
//So this is a step into building the final product done by the builder.
THIS^.localProduct.part2 := part2;
-------------------------------------------------------------------------------
Set_Part3
-------------------------------------------------------------------------------

                        Illustrative method of the pattern to set the part3


METHOD Set_Part3: 

VAR_INPUT
    part3: string;
END_VAR
//Sets the passed value to its corresponding field. 
//We can say that the the final product is in process of being built.
//So this is a step into building the final product done by the builder.
THIS^.localProduct.part3 := part3;  
-------------------------------------------------------------------------------
Get_Main_Part
-------------------------------------------------------------------------------

                        Illustrative method of the pattern to get the main part


METHOD Get_Main_Part: string
//Returns the object stored in the built product THIS^.localProduct.mainPart
Get_Main_Part := THIS^.localProduct.mainPart;
-------------------------------------------------------------------------------
Get_Part1
-------------------------------------------------------------------------------

                        Illustrative method of the pattern to get the part1


METHOD Get_Part1: string
//Returns the object stored in the built product THIS^.localProduct.part1
Get_Part1 := THIS^.localProduct.part1;
-------------------------------------------------------------------------------
Get_Part2
-------------------------------------------------------------------------------

                        Illustrative method of the pattern to get the part2


METHOD Get_Part2: string
//Returns the object stored in the built product THIS^.localProduct.part2
Get_Part2 := THIS^.localProduct.part2;
-------------------------------------------------------------------------------
Get_Part3
-------------------------------------------------------------------------------

                        Illustrative method of the pattern to get the part3


METHOD Get_Part3: string
//Returns the object stored in the built product THIS^.localProduct.part3
Get_Part3 := THIS^.localProduct.part3;
-------------------------------------------------------------------------------
Get_Result
-------------------------------------------------------------------------------

                        Illustrative method of the pattern


METHOD Get_Result: Product
//The concrete builder, after it builts the final object of class product, returns the 
// final product object 
Get_Result := THIS^.localProduct;
-------------------------------------------------------------------------------
fb_init
-------------------------------------------------------------------------------


METHOD fb_init: 

VAR_INPUT
    bInitRetains: BOOL;
    bInCopyCode: BOOL;
    specs: ARRAY [..] OF ;
END_VAR
//Stores the specifications on its own specifications field.
THIS^.specifications := specs;
-------------------------------------------------------------------------------
Director
-------------------------------------------------------------------------------

                  The director class is responsible to delegate the construction of the final product object 
 to a concrete builder object.


FUNCTION_BLOCK Director

VAR_INPUT
    inputConcreteBuilder: ConcreteBuilder;
END_VAR

VAR
    concreteBuilder: ConcreteBuilder;
END_VAR
//Stores the reference to which builder will be building the final product object in its own field THIS^.concreteBuilder
THIS^.concreteBuilder := inputConcreteBuilder;
-------------------------------------------------------------------------------
fb_init
-------------------------------------------------------------------------------

                        This constructor is called at instanciation it is necessary to instanciate the Director instance.
The specifications of the concreteBuilder instance stored in the Director instance should be set first by the client
 otherwise a Data Recursion error is caused


METHOD fb_init: 

VAR_INPUT
    bInitRetains: BOOL;
    bInCopyCode: BOOL;
    inputConcreteBuilder: ConcreteBuilder;
END_VAR

VAR
    defaultArray: ARRAY [..] OF ;
END_VAR
//Creates the concreteBuilder instance that will be building the final product object in its own field THIS^.concreteBuilder
//This instance is empty because we can not use Data Recursion with the inputConcreteInstance instanciation.
//So this concreteBuilder instance should be changed by the client before a Construct() request is called on the Director for the first time only.
THIS^.concreteBuilder := inputConcreteBuilder;
-------------------------------------------------------------------------------
Construct
-------------------------------------------------------------------------------

                        This method is going to be called by the client when a new Product object must be built


METHOD Construct: Product
//The Director tells its concreteBuilder instance to build the final product step by step passing the specifications stored in the 
// concreteBuilder array THIS^.specifications[1..4]

//Step 1 "Main Part"
THIS^.concreteBuilder.Set_Main_Part(THIS^.concreteBuilder.specifications[1]);
//Step 2 "Part 1"
THIS^.concreteBuilder.Set_Part1(THIS^.concreteBuilder.specifications[2]);
//Step 3 "Part 2"
THIS^.concreteBuilder.Set_Part2(THIS^.concreteBuilder.specifications[3]);
//Step 4 "Part 3"
THIS^.concreteBuilder.Set_Part3(THIS^.concreteBuilder.specifications[4]);

//Finally the concreteBuilder instance in the Director object delivers the final result as a Product object
Construct := THIS^.concreteBuilder.Get_Result();
-------------------------------------------------------------------------------
Product
-------------------------------------------------------------------------------

                  The class Product is just a plain bluprint of the components of the object to be built.
The final Product may ot may not contain the all the Parts listed on the Product declaration
 rather only the parts in the specifications sent by the client.


FUNCTION_BLOCK Product

VAR_INPUT
    mainPart: string;
    part1: string;
    part2: string;
    part3: string;
END_VAR

-------------------------------------------------------------------------------
toString
-------------------------------------------------------------------------------

                        Method to be used in the visualization element for an easier String handling


METHOD toString: string

VAR
    tempString: string;
END_VAR
//tempString joins together "Main Part" and "Part 1" of the Product object
tempString := CONCAT(THIS^.mainPart , THIS^.part1);
//tempString joins together its current value and "Part 2" of the Product object
tempString := CONCAT(tempString , THIS^.part2);
//tempString joins together its current value and "Part 3" of the Product object
tempString := CONCAT(tempString , THIS^.part3);
//The final result is sent as the output of this method
toString := tempString;