Simple explanation for Builder Pattern
Situation: You’re Creating a User Object
Simple class. A User has:
- name
So you write a constructor. Done.
Then Product Team Comes In
“Actually, we also want to track:”
- phone number
- address
- birthdate
- isSubscribed
- profilePictureUrl
- …and 10 more fields (some optional, some required, some only needed in certain flows).
Now you’re staring at your constructor like:
User user = new User(“John”, “[email protected]”, null, null, true, null, …);
It’s ugly. It’s unreadable. You forget which parameter is which.
And you’re scared to touch it.
What’s the Problem?
- Your constructors are overloaded and confusing.
- Too many optional fields = hard to manage.
- Setting values using setters feels unsafe - object might be in an invalid state.
- Code becomes hard to read and maintain.
How Builder Pattern Saves You
Builder says:
“Don’t pass everything in one shot. Let’s build the object step-by-step - only what you need.”
So instead, you do:
User user = new UserBuilder()
.withName("John")
.withEmail("[email protected]")
.withSubscribed(true)
.build();
- Clear
- Readable
- No confusion about parameter order
- Object is created only after all the required stuff is set
You can even make the builder validate required fields before allowing .build()
.
When Should You Use It?
- When object has lots of optional fields
- When constructor overloads are getting out of control
- When you want to enforce immutable, clean object creation
- When chaining setup makes code easier to read
Real World Dev Examples
- StringBuilder in Java
- AlertDialog.Builder in Android
- Request.Builder in OkHttp
- Any API client config objects
Builders are everywhere when the object is complex.