80 likes | 259 Views
Creational Pattern: Builder. Chapter 3 – Page 23. When a complex object needs to be created, it is sometimes beneficial to separate the construction of the object from its representation.
E N D
Creational Pattern: Builder Chapter 3 – Page 23 When a complex object needs to be created, it is sometimes beneficial to separate the construction of the object from its representation. 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 Pattern Chapter 3 – Page 24 The Builder is an abstract interface for constructing objects. 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 Example Chapter 3 – Page 25 The Cook director uses the abstract PizzaBuilder builder to construct the Pizza product piece by piece. 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).
Distributed Computing Example Chapter 3 – Page 26 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). 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 Chapter 3 – Page 27 #include <iostream> #include <string> using namespace std; enumPersistenceType { File, Queue, Pathway }; structPersistenceAttribute { PersistenceType type; string value; }; classDistributedWorkPackage { public: DistributedWorkPackage(string type) { cout << desc << "Distributed Work Package for: " << type; } voidsetFile(string filetype, string value) { cout << temp << endl << " File(" << filetype << "): " << value; desc = desc + temp; } voidsetQueue(string queuetype, string value) { cout << temp << endl << " Queue(" << queuetype << "): " << value; desc = desc + temp; } voidsetPathway(string pathwaytype, string value) { cout << temp << endl << " Pathway(" << pathwaytype << "): " << value; desc = desc + temp; } const string getState() { returndesc; } private: string desc, temp; };
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; }; classUnixBuilder: public Builder { public: UnixBuilder() { result = newDistributedWorkPackage("Unix"); } voidconfigureFile(string name) { result->setFile("flatFile", name); } voidconfigureQueue(string queue) { result->setQueue("FIFO", queue); } voidconfigurePathway(string type) { result->setPathway("thread", type); } }; classVmsBuilder: public Builder { public: VmsBuilder() { result = newDistributedWorkPackage("Vms"); } voidconfigureFile(string name) { result->setFile("ISAM", name); } voidconfigureQueue(string queue) { result->setQueue("priority", queue); } voidconfigurePathway(string type) { result->setPathway("LWP", type); } }; class Reader { public: voidsetBuilder(Builder *b) { builder = b; } voidconstruct(PersistenceAttributelist[], intnum); private: Builder *builder; }; Chapter 3 – Page 28
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 intNUM_ENTRIES = 6; PersistenceAttribute input[NUM_ENTRIES] = { { File, "state.dat" }, { File, "config.sys" }, { Queue, "compute" }, { Queue, "log" }, { Pathway, "authentication" }, { Pathway, "error processing" } }; void main() { UnixBuilderunixBuilder; Reader reader; reader.setBuilder(&unixBuilder); reader.construct(input, NUM_ENTRIES); cout << unixBuilder.getResult()->getState() << endl << endl; VmsBuildervmsBuilder; reader.setBuilder(&vmsBuilder); reader.construct(input, NUM_ENTRIES); cout << vmsBuilder.getResult()->getState() << endl << endl; } Chapter 3 – Page 29
Builder Design Advantages Chapter 3 – Page 30 • 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.