design-patternsbuilder

Builder design pattern: Why do we need a Director?


Recently I've come across the Builder design pattern. It seems that different authors use "Builder pattern" to refer to different flavours, so let me describe the pattern I'm asking about.

We have an algorithm for creating products, i.e., objects of different types. At a sufficiently high level of abstraction the algorithm is the same for all product types, but each product type requires a different implementation of each of the algorithm's abstract steps. For example, we might have the following cake-baking algorithm:

  1. Add liquids.
  2. Mix well.
  3. Add dry ingredients.
  4. Mix well.
  5. Pour batter into baking pan.
  6. Bake.
  7. Return baked cake.

Different cakes would require different implementations of these steps, i.e., what liquids/dry ingredients to use, what speed to mix at, how long to bake, etc.

The pattern says to do it like so. For each product we create a concrete builder class with an implementation for each of the above steps. All of these classes are derived from an abstract builder base class, which is essentially an interface. So, for example, we will have an abstract base class CakeBaker with pure virtual methods AddLiquid(), MixLiquids(), etc. The concrete cake bakers will be concrete subclasses, e.g.,

class ChocolateCakeBaker : public CakeBaker {
public:
   virtual void AddLiquids()
   {
        // Add three eggs and 1 cup of cream
   }

   virtual void AddDryIngredients()
   {
       // Add 2 cups flour, 1 cup sugar, 3 tbsp cocoa powder,
       // 2 bars ground chocolate, 2 tsp baking powder
   }
      ...
      ...
};

The LemonCitrusCakeBaker would also be a subclass of CakeBaker, but would use different ingredients and quantities in its methods.

The different cake types will similarly be subclasses of an abstract Cake base class.

Finally, we have a class to implement the abstract algorithm. This is the director. In the bakery example we might call it ExecutiveBaker. This class would accept (from the client) a concrete builder object and use its methods in order to create and return the desired product.

Why do we need the director to be separate from the abstract builder? Why not roll them into a single builder abstract base class, making the original abstract builder's public methods protected (and the concrete subclasses override these as before).


Solution

  • The core portion of the Builder pattern concerns the Abstract Builder and its subclasses (concrete builders). According to GoF's Design Patterns, director simply "notifies the builder whenever a part of the product should be built", which can be perfectly done by the client.

    The StringBuilder class in the Java API is an example of a builder without the respective director -- typically the client class "directs" it.

    Also, in Effective Java and Creating and Destroying Java Objects, Joshua Bloch suggests the use of the builder pattern, and he does not include a director.