//---------------------------------------------------------------------------------------------- //BUILDER - A CREATIONAL PATTERN // | INTENT // |  | for a complex object // |  |  | separate its construction from representation // |  |  | same construction process // |  |  |  | can create different representations // | APPLICABILITY ----------------------------------------------------------------------------- // |  | algorithm for creating a complex object should be // |  |  | independent of the parts // |  |  |  | that make up the object // |  |  |  | how they're assembled // |  | construction // |  |  | must allow different representations // | STRUCTURE // |  |                                        builder // |  |        |          Director          |o------------>|  Builder  | // |  |        |-----------------------------|              |-----------| // |  |        |Construct()                  |              |BuildPart()| // |  |        | for all objects in structure|                    ^ // |  |        |  builder.BuildPart()        |                    | // |  |                                                    |ConcreteBuilder|- - - - ->|Product| // |  |                                                    |---------------| // |  |                                                    |BuildPart()    | // |  |                                                    |GetResult()    | // | PARTICIPANTS // |  | Builder // |  |  | abstract interface // |  |  |  | for creating product parts // |  | ConcreteBuilder // |  |  | constructs and assembles product parts // |  |  |  | by implementing the builder interface // |  |  | defines and keeps track of the representation it creates // |  |  | provides an interface for retrieving the product // |  | Director // |  |  | constructs an object // |  |  |  | using the builder interface // |  | Product // |  |  | represents the complex object under construction // |  |  |  | ConcreteBuilder // |  |  |  |  | builds the product's internal representation // |  |  |  |  | defines the process by which it's assembled // |  |  | includes // |  |  |  | classes that define the constituent parts // |  |  |  | interfaces for assembling the parts into the final result // | COLLABORATIONS ---------------------------------------------------------------------------- // |  | Client // |  |  | creates the Director object // |  |  | configures it with the desired Builder object // |  | Director // |  |  | notifies the builder whenever a part of the product should be built // |  | Builder // |  |  | handles requests from the director // |  |  | adds parts to the product // |  | Client // |  |  | retrieves the product from the builder // |  | // |  |    aClient                              aDirector          aConcreteBuilder // |  |        |                                      |                      | // |  |      | |new ConcreteBuilder                                        | // |  |      | |- - - - - - - - - - - - - - - - - - -|- - - - - - - - - - >| | // |  |      | |                                                          | | // |  |      | |new Director(aConcreteBuilder)      |                      | // |  |      | |- - - - - - - - - - - - - - - - - ->| |                    | // |  |      | |                                    | |                    | // |  |      | |                                    |                      | // |  |      | |Construct()                          |                      | // |  |      | |----------------------------------->| |BuildPartA()        | // |  |      | |                                    | |------------------->| | // |  |      | |                                    | |                    | | // |  |      | |                                    | |                    | // |  |      | |                                    | |BuildPartB()        | // |  |      | |                                    | |------------------->| | // |  |      | |                                    | |                    | | // |  |      | |                                    | |                    | // |  |      | |                                    | |BuildPartC()        | // |  |      | |                                    | |------------------->| | // |  |      | |                                    | |                    | | // |  |      | |                                    |                      | // |  |      | |GetResult()                          |                      | // |  |      | |-------------------------------------|-------------------->| | // |  |      | |                                    |                    | | // |  |        |                                      |                      | // |  | // | CONSEQUENCES // |  | It lets you vary product's internal representation // |  |  | define a new kind of builder // |  | Isolates code for construction and representation // |  |  | ConcreteBuilder // |  |  |  | contains all the code // |  |  |  |  | to create and assemble a product // |  |  | code is written once // |  |  |  | Directors can reuse it // |  |  |  |  | same set of parts to build Product variants // |  | Finer control over the construction // |  |  | step by step // |  |  |  | construction of the product under the director's control // |  |  | finished product // |  |  |  | retrieved by the director from the builder // | IMPLEMENTATION ---------------------------------------------------------------------------- // |  | Operation for each component defined by Builder // |  |  | does nothing by default // |  | Assembly and construction interface // |  |  | step-by-step fashion // |  |  | general interface for all kinds of concrete builders // |  |  |  | a model where // |  |  |  |  | construction results are appended to the product // |  |  |  |  |  | is usually sufficient // |  |  |  | if parts constructed earlier must be accessed // |  |  |  |  | director receives child nodes from the builder // |  |  |  |  |  | passes them back to the builder to build the parent nodes // |  | No abstract class for products // |  |  | products differ greatly // |  |  | client is in a position to know // |  |  |  | concrete subclass of Builder in use // |  |  |  | can handle its products accordingly // |  | Empty methods as default in Builder // |  |  | clients override operations they're interested in // | CODE -------------------------------------------------------------------------------------- #include <SRCPatternsPatterns.mqh> namespace Builder { class Product   { public:   void              Add(string);   void              Show(); protected:   SAList            parts;   }; void Product::Add(string part) {parts+=part;} void Product::Show(void) {int c=parts.Count(); for(int i=0; i<c; i++) Print(parts[i]);} //---------------------------------------------------------------------------------------------- interface Builder   {   void BuildPartA();   void BuildPartB();   void BuildPartC();   Product* GetResult();   }; //---------------------------------------------------------------------------------------------- class Director   { public:   void              Construct();                     Director(Builder*);                     ~Director(); protected:   Builder*          builder;   }; void Director::Director(Builder *b) {builder=b;} void Director::~Director(void) {delete builder;} void Director::Construct(void)   {   builder.BuildPartA();   builder.BuildPartB();   builder.BuildPartC();   } //---------------------------------------------------------------------------------------------- class ConcreteBuilder:public Builder   { public:   void              BuildPartA();   void              BuildPartB();   void              BuildPartC();   Product*          GetResult(); protected:   Product          product;   }; //--- void ConcreteBuilder::BuildPartA(void) {product.Add("Part A");} void ConcreteBuilder::BuildPartB(void) {product.Add("Part B");} void ConcreteBuilder::BuildPartC(void) {product.Add("Part C");} Product* ConcreteBuilder::GetResult(void) {return &product;} //---------------------------------------------------------------------------------------------- class Client:public ClientExample {public: string Output(); void Run();}; string Client::Output() {return __FUNCTION__;} void Client::Run()   {   Builder* builder=new ConcreteBuilder;   Director director(builder);   director.Construct();   Product* product=builder.GetResult();   product.Show();   } } //OUTPUT --------------------------------------------------------------------------------------- // | Creational::Builder::Client::Output // | Part A // | Part B // | Part C