The builder creational pattern allows you to hide all the details needed to create a complicated object behind simple steps that another object will direct. This lets you change either how things get built or the steps that are used independently of each other.
This pattern describes how you might have an abstract class called a builder with maybe three methods: addStory, addRoom, and addDoor
The addStory method can be called many times to make the building higher. The builder will decide what needs to be done to support such a short or tall building.
The addRoom method will add a room to a specific story. The director can call this method to add various rooms. The builder will decide how and where to place walls to get the desired effect.
The addDoor method will be called to add a door between two rooms or between a room and the outside.
And this design pattern describes how a client will be the one to actually choose a specific concrete builder class that derives from the abstract builder class. The client also selects a director and provides the builder to the director. The director only knows about the builder through the base class interface.
With this pattern, different directors can be selected that will call the builder methods to direct the construction of various building. And different builder can be selected that will carry out these instructions.
If the client selects a director that knows how to build a simple house in the suburbs but provides a shipBuilder for the builder, then what gets built will resemble a small sized yacht instead of a 3 bedroom house.
Listen to the full episode or you can also read the full transcript below.
The basic description says that this pattern separates the construction of complex objects from their representation so that the same construction process can create different representations.
Alright, let me try to explain what that means so you can understand it. I haven’t used an example of building a house yet, so let’s use that for today’s analogy.
One way to think of building a house would be to:
◦ #1 build the foundation
◦ #2 build the floor
◦ #3 build the walls
◦ #4 build the room
◦ #5 add the windows and doors
◦ and #6 add all the trim such as flooring, lighting, appliances, etc.
That’s not the way this pattern works. I just wanted to mention it to get this out of the way. You see, all of those things are the details that this pattern is supposed to hide behind the representation. There’s a lot more details that I completely skipped but are actually very important. For example plumbing. Or heating. Wouldn’t be much of a house without those.
But different buildings either for different purposes such as commercial vs. residential, or in different locations such as cold northern regions vs. tropics, or since this is software we’re talking about for actual building vs. testing purposes will each have drastically different ideas of what details are important. So let’s let the builder classes worry about those details.
What we do is create an abstract builder class that has simple steps for building a house and then concrete builder classes that actually do whatever they need to do.
So if steps like building the foundation, floor, and walls is not correct, then what kinds of steps should the abstract builder define? I’ll explain this right after this message from our sponsor.
( Message from Sponsor )
The steps I listed earlier are not just the wrong steps because of the details, they also don’t allow much variation in what gets built. The description of this pattern described how you could have different builders that each built something different. But I think it missed another important aspect. And that’s the ability to have different directors. What’s a director? In this pattern, you have a client which is in control of everything. This is very similar to real life. I’m not making this up.
I keep telling everybody about how easy it is to learn how to program if you just think about programming as it relates to real life scenarios. This is a really good example.
Okay, so the client knows what it wants to build and selects a specific concrete builder. A company would select a commercial builder class. A young couple just starting out would select a simple home builder for whatever climate best fits their area. A software test engineer would select a builder that just keeps track of everything without actually building anything so the result can be compared with another result to look for bugs.
Once the specific builder class is selected, the client also needs to select a director and let the director know about the builder that was chosen. This step deviates a bit from real life. In real life, this step would match the selection of a contractor and and some blueprints. Here, the director may or may not need any plans. Some directors just know how to build one type of building. Other directors might know a bit more and understand how to read the plans from a file. When I say that a director just knows how to build one type of building, remember that this is from the director’s perspective. The director just issues commands to the builder. It’s the builder that actually turns those commands into the finished product.
What kind of steps are appropriate then? For that, we need to think more in terms of what the client wants instead of what we think needs to happen. Instead of assuming that we need a foundation, we let the concrete builder decide that. I mean if this is a builder for a jungle hut, then we certainly don’t need a foundation. We don’t even need a floor. What we do want are rooms, doors, windows, and even levels. Some builders might decide to completely ignore steps. Or to take drastic or unexpected actions to accomplish the steps. That’s all up to the builder. Instead of the steps that I listed earlier, more appropriate steps for this pattern to build a house would be:
◦ #1 Add a first story
◦ #2 Add a second story
◦ #3 Add a room #1 with an entry on the first story
◦ #4 Add a room #2 with a garage door on the first story
◦ #5 Add a door connecting rooms 1 and 2
A builder interface that allows for steps like these can now support directors that want to build a house in the suburbs or a 10 story office building. You want to find steps that are common to various buildings and these are expressed in terms that the client may be interested in. Then you let the actual builder classes worry about all the details needed to construct whatever steps the director asks for.
When you follow this pattern, the director thinks it’s building a house and following the steps that it knows about. But behind the scenes, maybe the client has provided the director with a shipbuilder. As long as the shipbuilder can implement the methods in the abstract builder class, then the client ends up with a yacht instead of a two story house.