RAVAGE
I had a good discussion over the Builder pattern with my friend. Always he tries to map the pattern with a real case scenario and alters the example so as to fit it. So the problem is while discussing with him we need to think more than once before answering him. Also the important part I like with his discussion is that he tries to map the pattern as a pluggable element. That is he tries to identify the extensible part (reusable part for specific abstraction or mode) in order to scale-up the implementation. Actually that extensible part will be the core use of the pattern.
PLOT
A Product that need to be built step by step plays one of core role of this pattern. The ConcreteBuilder holds the functionalities for creating each part and accumulate them into a specific Product. The AbstractBuilder should provide common behaviors that supports different ConcreteBuilders. Director is the one who constructs the Product with the help of the operations specified by the Builder.
In the GOF structure client is not specified explicitly but the client plays an important role which specifies how the internal relationship will be executed. Client takes the responsibility for selecting the particular ConcreteBuilder and sends it to the Director. So the Client knows the ConcreteBuilder, Product and the Director.
GOF STRUCTURE
Please view the GOF structure in dofactory.
MATCHING SCENARIO
To understand simply we can take the common House example specified for this pattern. House is the product that we need to build. The ConcreteBuilder holds the operation for creating part of the object. One such operation is the method for creating room (CreateRoom()). As you know the AbstractBuilder holds the abstract description (simply abstract CreateRoom() here) that mimics the ConcreteBuilder. Now comes the Director which actually constructs the object for House using the AbstractBuilder. Let us consider the Director is going to create 2 bedroom flat, then it calls the CreateRoom() method in the AbstractBuilder (builder.CreateRoom()) twice.
Ok now we concentrate on how this will be implemented. As specified earlier, Client creates an instance for the specific ConcreteBuilder. Usually that ConcreteBuilder instance will be passed as an argument to the method call to the Director which holds the construction process.
EXTENSIONS
It is clear that Client is the one who decides which ConcreteBuilder need to be called. Hence the Client obviously knows which Product will get created. So he calls the construction operation in the Director passing the ConcreteBuilder instance.
Here comes the rival. My friend wants to explain the extension of this pattern by specifying an additional point in the above scenario. In our scenario we discussed about a 2 bedroom flat. He meant to extend it with 3 bedroom flat.
I just tried to extend with builder pattern but then inferred that the 3 bedroom scenario (in addition to 2 bedroom) partially won't suit the intent.
Actually as per the Intent specified by GOF for Builder pattern, the construction of complex object need to be separated from its representation so that the same construction process can be used for different representations. In our case the construction process is meant for a 2 bedroom flat and so in order to extend that, we need to identify a scenario that fits the different representation for the same 2 bed room construction. Hence we decided to go with two different representations of the 2 bedroom flat,
1) ordinary flat - whose CreateRoom() will create wall of thickness 200mm with ceiling height 10ft 2) secured flat - whose CreateRoom() will create wall of thickness 500mm with ceiling height 16ft.
For this we simply need to add a new ConcreteBuilder for the secured flat which uses the same AbstractBuilder as before.
Fine, now let us shift our focus to the 3 bedroom flat. Whether this can't be done with builder pattern? Not like that, it can be. So only previously in this post I specified it as "partially won't suit". Just introduce a separate construction process in the Director for the 3 bedroom flat (CreateRoom() need to be called 3 times). Since the Client is the one who is going to call the Director and also he has the knowledge on ConcreteBuilder and the Product, he'll take care of it and have control over it.
SUMMARY
- Need to identify the parts for building the complex object and ConcreteBuilder should provide the basic operations for creating parts for a specific Product.
- AbstractBuilder should be common so as to accommodate different ConcreteBuilders.
- Director will construct the object by calling the basic operations for creating the parts.
- Client will decide which ConcreteBuilder instance to be used and pass it as parameter to the operation in the Director. Also Client have the knowledge of which Product to be created.
REFERENCE
For references and more info:
Design Patterns: Elements of Reusable Object-Oriented Software
http://www.dofactory.com/Patterns/PatternBuilder.aspx