We want to separate the construction of an assembly from the construction of its components.
Encapsulate the assembly construction process in a component called the director. Encapsulate the construction of the components in a component called the builder.
Builders are similar to abstract factories. There are two differences. First, the job of building the assembly is given to a component called the Director. Second, the components are created and added to the assembly by the builder.
Here is the abstract base class for all builders:
class Builder
{
protected:
Assembly* a = 0;
public:
virtual void addComponentA() = 0;
virtual void addComponentB() = 0;
// etc.
Assembly* getAssembly() { return a; }
};
A concrete builder instantiates a concrete assembly and implements the methods for building and adding concrete components to this assembly:
class ConcreteBuilder: public Builder
{
private:
class ConcreteComponentA: ComponentA {
... };
class ConcreteComponentB: ComponentB {
... };
class ConcreteAssembly: Assembly { ...
};
public:
ConcreteBuilder(){ a = new
ConcreteAssembly(); }
void addComponentA() { a->add(new
ConcreteComponentA(); }
void addComponentB() { a->add(new
ConcreteComponentB(); }
};
The process for adding components to the assembly is implemented by the director:
class Director
{
public:
void makeAssembly(Builder* b)
{
b->addComponentA();
b->addComponentB();
// etc.
}
};
Here is how a client builds an assembly:
Builder* b = new ConcreteBuilder();
Director d;
d.makeAssembly(b);
Assembly a = b->getAssembly();