When creating objects in programming, sometimes we need to set many optional values. If we use constructors for this, it can get messy quickly and cause constructor hell. The builder pattern helps us solve this problem by providing a step-by-step way to create objects.
Why Use the Builder Pattern?
Consider a User
class where some properties (like age
and email
) are optional. Without the Builder Pattern, you might need multiple constructors or pass undefined
for missing values. This can make code hard to read.
The Builder Pattern solves this by:
- Making object creation more readable.
- Avoiding unnecessary or confusing constructor arguments.
Example: Creating a User Object with a Builder
Let's take a look at how the Builder Pattern works in TypeScript.
Step 1: Define the User
Class
class User {
constructor(
public name: string,
public age?: number,
public email?: string
) {}
}
This User
class has three properties: name
, age
, and email
. Only name
is required.
Step 2: Create a UserBuilder
Class
interface IUserBuilder {
setName(name: string): this;
setAge(age: number): this;
setEmail(email: string): this;
build(): User;
}
class UserBuilder implements IUserBuilder {
private user: Partial<User> = {};
setName(name: string): this {
this.user.name = name;
return this;
}
setAge(age: number): this {
this.user.age = age;
return this;
}
setEmail(email: string): this {
this.user.email = email;
return this;
}
build(): User {
if (!this.user.name) {
throw new Error("User must have a name");
}
return new User(this.user.name, this.user.age, this.user.email);
}
}
Step 3: Using the UserBuilder
const user = new UserBuilder()
.setName("John Doe")
.setAge(35)
.setEmail("johndoe@email.com")
.build();
console.log(user);
Output:
User { name: 'John Doe', age: 35, email: 'johndoe@email.com' }
If we try to create a user without a name, we get an error:
const newUser = new UserBuilder().setAge(70).build(); // Error: User must have a name
Benefits of Using the Builder Pattern
✅ Improves readability – Each property is set explicitly.
✅ Reduces constructor overloads – No need to pass undefined
for optional parameters.
✅ Flexible object creation – Easily add or remove properties without modifying the constructor.
When to Use the Builder Pattern
Use the Builder Pattern when:
- You have a class with many optional properties.
- You want to make object creation more readable.
- You want to enforce required fields before creating the object.
Conclusion
The Builder Pattern is a simple yet powerful way to create objects, especially when dealing with optional parameters. It makes your code cleaner, easier to understand, and less error-prone.
I am implementing design patterns in Go, Python, and TypeScript. You can find the repository here.
Happy coding! 🚀
Top comments (0)