Day 2: Builder Pattern
Welcome to my 30-Day Design Pattern Challenge! Today, we’re going to explore the Builder Pattern, a creational design pattern that helps you construct complex objects step by step.
What is the Builder Pattern?
The Builder Pattern is a design pattern that separates the construction of complex objects from their representation. It allows you to construct different representations of an object using the same construction code.
Intent
The intent of the Builder Pattern is to provide a flexible way to create complex objects without coupling the construction process to the object’s representation.
Problem
Imagine you’re building a complex object with many fields and nested objects. You might end up with a telescoping constructor, making it hard to maintain and extend.
Solution
The Builder Pattern solves this problem by introducing a separate object, the Builder, which constructs the complex object step by step. This way, you can create different representations of the object without changing the construction code.
Class Diagram
The class diagram consists of the following entities:
- Builder: An interface or abstract class that defines the steps for constructing an object.
- Concrete Builder: A class that implements the Builder interface and provides specific implementation for each step.
- Director: A class that directs the construction process and returns the final product.
- Product: The complex object being constructed.
Code Examples
Let’s consider building a car object with different features like engine, wheels, and interior. We can create a CarBuilder
interface with steps for building each feature.
public interface CarBuilder {
void buildEngine();
void buildWheels();
void buildInterior();
Car getResult();
}
We can then create concrete builders for different types of cars, like SedanBuilder
and SUVBuilder
.
public class SedanBuilder implements CarBuilder {
private Car car;
@Override
public void buildBody() {
// build sedan body
}
@Override
public void buildEngine() {
// build sedan engine
}
@Override
public void buildWheels() {
// build sedan wheels
}
@Override
public void buildInterior() {
// build sedan interior
}
@Override
public Car getResult() {
return car;
}
}
public class SUVBuilder implements CarBuilder {
private Car car;
@Override
public void buildBody() {
// build SUV body
}
@Override
public void buildEngine() {
// build SUV engine
}
@Override
public void buildWheels() {
// build SUV wheels
}
@Override
public void buildInterior() {
// build SUV interior
}
@Override
public Car getResult() {
return car;
}
}
We can then create director class which directs the construction process and returns the final product.
public class Director {
private CarBuilder carBuilder;
public Director(CarBuilder carBuilder) {
this.carBuilder = carBuilder;
}
public void construct(boolean isSUV) {
carBuilder.buildBody();
carBuilder.buildEngine();
carBuilder.buildWheels();
if (isSUV)
carBuilder.buildInterior();
}
public Car getResult() {
return carBuilder.getResult();
}
}
Then our Client class uses the Director to construct different types of cars by passing in the appropriate builder. It can then call the getResult() method to get the final product, which is a Car object.
public class Client {
public void main() {
SedanBuilder sedanBuilder = new SedanBuilder();
Director director = new Director(sedanBuilder);
director.construct(false);
Car sedan = director.getResult();
SUVBuilder suvBuilder = new SUVBuilder();
director = new Director(suvBuilder);
director.construct(true);
Car suv = director.getResult();
}
}
Benefits
- Separates construction from representation
- Provides flexibility in creating complex objects
- Improves maintainability and extensibility
Disadvantages
- Can be overkill for simple objects
- Requires more classes and interfaces
When to Use
- When creating complex objects with multiple fields and nested objects
- When you need to create different representations of an object
When Not to Use
- For simple objects with few fields
- When the construction process is trivial
Conclusion
That’s it for today’s post on the Builder Pattern! I hope you enjoyed learning about this creational design pattern. Stay tuned for the next post, where we will dive into the Singleton Pattern!
Join me on this 30-day journey, and let’s explore the world of design patterns together! If you have any questions or feedback, please leave a comment below. I’d love to hear from you!