Creational Pattern: Builder When a complex object needs to be created, it is sometimes beneficial to...
-
Upload
augustus-gordon -
Category
Documents
-
view
213 -
download
1
Transcript of Creational Pattern: Builder When a complex object needs to be created, it is sometimes beneficial to...
Creational Pattern: BuilderWhen a complex object needs to be created, it is sometimes beneficial to separate the construction of the object from its representation.
Chap
ter 3
– Pa
ge 1
In this way, the same construction process may be utilized to create different representations of the object.
A “director” invokes the “builder” as an interface, which creates part of the complex object each time it’s called, maintaining all intermediate states.When the product is finished, the client retrieves the result from the “builder”.
The Builder PatternThe Builder is an abstract interface for constructing objects.
Chap
ter 3
– Pa
ge 2
Director
Construct()
ProductConcreteBuilder
BuildPart()GetResult()
Builder
BuildPart()
for each item in structure builder.BuildPart()
The ConcreteBuilder provides the Builder’s implementation, constructing and assembling parts to build objects.The Director is responsible for managing the correct sequence of object creation, receiving a ConcreteBuilder as a parameter and executing the necessary operations on it.The Product is the final object created by the Director, using the Builder.
Non-Software ExampleThe Cook director uses the abstract PizzaBuilder builder to construct the Pizza product piece by piece.
Chap
ter 3
– Pa
ge 3
By invoking a particular concrete builder (HawaiianPizzaBuilder or SpicyPizzaBuilder), the Pizza that is produced is polymorphic (i.e., either a thin-crust, mild-sauce, ham/pineapple-topped Pizza from a HawaiianPizzaBuilder or a pan-crust, hot-sauce, sausage/pepperoni-topped Pizza from a SpicyPizzaBuilder).
Pizza
setDough()setSauce()setTopping()
HawaiianPizzaBuilder
BuildDough()BuildSauce()BuildTopping()
Cook
SetPizzaBuilder()GetPizza()ConstructPizza()
PizzaBuilder
GetPizza()CreateNewPizzaProduct()BuildDough()BuildSauce()BuildTopping()
constructPizza() pizzaBuilder.BuildDough() pizzaBuilder.BuildSauce() pizzaBuilder.BuildTopping()
SpicyPizzaBuilder
BuildDough()BuildSauce()BuildTopping()
Distributed Computing Example
The Reader director (i.e., a parser) uses the abstract Builder to construct the DistributedWorkPackage product piece by piece (i.e., to prepare it for the server to send to the appropriate client machine).
Chap
ter 3
– Pa
ge 4
DistributedWorkPackage
UnixBuilder
ConfigureFile()ConfigureQueue()ConfigurePathway()
Reader
Construct()
Builder
GetResult()ConfigureFile()ConfigureQueue()ConfigurePathway()
The Reader retrieves the archived specification of the DistributedWorkPackage, delegating each build step to the builder that was registered by the client.
VmsBuilder
ConfigureFile()ConfigureQueue()ConfigurePathway()
By invoking a particular concrete builder (UnixBuilder or VmsBuilder), the work package that is produced is polymorphic (i.e., either a flat-file, FIFO-queue, thread-pathway work package from a UnixBuilder or an indexed-sequential-file, priority-queue, lightweight-process-pathway work package from a VmsBuilder).
Work Package Builder C++ Code
Chap
ter 3
– Pa
ge 5
#include <iostream>#include <string>using namespace std;
enum PersistenceType { File, Queue, Pathway };
struct PersistenceAttribute { PersistenceType type; string value;};
class DistributedWorkPackage { public: DistributedWorkPackage(string type) { cout << desc << "Distributed Work Package for: " << type; } void setFile(string filetype, string value) { cout << temp << endl << " File(" << filetype << "): " << value; desc = desc + temp; } void setQueue(string queuetype, string value) { cout << temp << endl << " Queue(" << queuetype << "): " << value; desc = desc + temp; } void setPathway(string pathwaytype, string value) { cout << temp << endl << " Pathway(" << pathwaytype << "): " << value; desc = desc + temp; } const string getState() { return desc; } private: string desc, temp; };
Chap
ter 3
– Pa
ge 6
class Builder { public: virtual void configureFile(string name) = 0; virtual void configureQueue(string queue) = 0; virtual void configurePathway(string type) = 0; DistributedWorkPackage *getResult() { return result; } protected: DistributedWorkPackage *result;};
class UnixBuilder: public Builder { public: UnixBuilder() { result = new DistributedWorkPackage("Unix"); } void configureFile(string name) { result->setFile("flatFile", name); } void configureQueue(string queue) { result->setQueue("FIFO", queue); } void configurePathway(string type) { result->setPathway("thread", type); }};
class VmsBuilder: public Builder { public: VmsBuilder() { result = new DistributedWorkPackage("Vms"); } void configureFile(string name) { result->setFile("ISAM", name); } void configureQueue(string queue) { result->setQueue("priority", queue); } void configurePathway(string type) { result->setPathway("LWP", type); }};
class Reader { public: void setBuilder(Builder *b) { builder = b; } void construct(PersistenceAttribute list[], int num); private: Builder *builder; };
Chap
ter 3
– Pa
ge 7
void Reader::construct(PersistenceAttribute list[], int num) { for (int i = 0; i < num; i++) if (list[i].type == File) builder->configureFile(list[i].value); else if (list[i].type == Queue) builder->configureQueue(list[i].value); else if (list[i].type == Pathway) builder->configurePathway(list[i].value);}
const int NUM_ENTRIES = 6;
PersistenceAttribute input[NUM_ENTRIES] = { { File, "state.dat" }, { File, "config.sys" }, { Queue, "compute" }, { Queue, "log" }, { Pathway, "authentication" }, { Pathway, "error processing" } };
void main(){ UnixBuilder unixBuilder; Reader reader; reader.setBuilder(&unixBuilder); reader.construct(input, NUM_ENTRIES); cout << unixBuilder.getResult()->getState() << endl << endl; VmsBuilder vmsBuilder; reader.setBuilder(&vmsBuilder); reader.construct(input, NUM_ENTRIES); cout << vmsBuilder.getResult()->getState() << endl << endl;}
Builder Design Advantages
Chap
ter 3
– Pa
ge 8
• The Builder pattern ensures that all steps to create a product are carried out in the appropriate order without burdening the client with the details. At the same time, however, it affords the client the flexibility to substitute methods and components as long as the substitutions don’t damage the building process.
• While the Abstract Factory pattern focuses on what is being built, the Builder pattern concentrates on how it is being built. When the object being produced is particularly complex, the Builder pattern provides finer control over the step-by-step construction process.