Builder pattern is an object creational software design pattern. This pattern is often compared with “Factory” method pattern because factory method is also an object creational DP. The key difference is how the object is being created though. For example with the factory DP,
createCar might return
Audi. To add attributes, you will need to make additional calls such as
setEngine etc on the object returned. Now with the Builder pattern, you could be specific about the object all in one statement, such as 4 all-wheel drive red
Honda with v6 engine etc. Basically, factory method pattern would create an object via
createCar VS Builder pattern has the ability to create an object by adding granularity to the object by applying chains of function calls to the object being created.
Here is a comparison of diagrams from the wiki for both pattern, which could give you a big picture of how they work.
I know, it’s actually hard to explain their differences just from the diagrams. So let me give you some code comparison in Java:
An example is from Wikipedia that matches with the diagram above exception
OrdinaryRoom are added to provide you with the picture on how multiple different instances are being created from a generic template.
Watch closely how it makes an
magicGame objects which both will eventually inherit from MazeGame. To give you the full picture,
OrdinaryMazeGame will create 2 rooms with
OrdinaryRoom objects in the
List<Room> rooms created by,
MagicMazeGame will create 2 rooms with
MagicRoom this time created by the parent,
MazeGame. Like a real Factory, the task it does is just to construct objects.
Builder pattern in my personal opinion is well described and explained in Effective Java (Second Ed) by Joshua Bloch. Here is the example from his book:
With the builder, it would be possible to do a chain-call, like
new NutritionFacts.Builder(240, 8).calories... etc, which would help greatly in terms of readability. From my experience with the Builder, this is the most important factor, “readability”: they carry “names” to what/how you define the object. Let me just give you an example that will say everything about what I just said. Say you have a constructor,
new Person(true, false, false, "Samsung"); vs with Builder, `new Person.Builder().hasBeard(true).isMarried(false).isDisabled(false). You know what I mean… Oh, there is another point I’d like to mention about the Builder. I recently came across a class with inheritance where I wanted to have the builder relationship. I actually ended up using “super” command. There is probably a better way to handle this in Generic but I wasn’t successful with using generics so I ended up sticking with “super” calls. Anyways, let me show you how I came across the Builder inheritance, below is just an illustration of what happened:
Then, let’s say
implements Person. Now, you can apply Composite design pattern:
Person p; as
p=new MathTeacher.Builder("calculus").name("Jane") or
p=new Teacher.Builder().name("Dan") etc… Anyways, Builder is powerful and very flexible on what and how you would like to create an object. There is only one disadvantage with the Builder. As you can see from above examples, you will end up introducing more lines of code. However, I prefer much in readability over the lines of code. Using the Builder will organize your constructor well and defined.