OOD Fundamentals
OOP Foundations
SOLID Principles
Structural Patterns
Behavioral Patterns
Classic OOD Problems: Part 1
Classic OOD Problems: Part 2
Builder Pattern
Imagine you are designing a User class for a web application. A user has a name, an email, and an age. Simple enough: three constructor parameters. Then requirements arrive: phone number, address, notification preferences, role, timezone, avatar URL, bio, two-factor authentication flag. Now your constructor takes 12 parameters.
This is the telescoping constructor problem. The name comes from what happens next: you write multiple constructor overloads, each adding one more parameter to the previous one, like segments of a telescope extending outward.
The creation call becomes unreadable:
What does True mean in position 6? What is 30? You cannot tell without checking the constructor signature. Passing None for every unused parameter is error-prone: swap two None values and the bug is silent.

Why Default Parameters Do Not Solve This
Languages with default parameters (Python, Kotlin, TypeScript) partially help: you can skip optional arguments. But the problem resurfaces when you need to set the 10th parameter without setting the 4th through 9th. In positional parameter languages like Java, you must pass every preceding argument. Even with named parameters, a constructor with 12 keyword arguments is hard to read and harder to maintain.
Why Setters Are Not the Answer Either
Another instinct is to use a no-argument constructor followed by setter calls:
This is readable, but it creates a dangerous window: between construction and the last setter call, the object is in an incomplete state. If someone passes the User to another method before calling set_email(), that method receives an invalid object with no email. There is no compile-time or runtime guarantee that all required fields are set. The object is mutable after construction, which invites accidental modification later.
The setter approach trades one problem (unreadable constructors) for a worse one (objects that exist in invalid states). A well-designed object should be valid from the moment it is created.
The core issue is that constructors force you to provide everything at once, while setters force you to provide everything piecemeal with no validation boundary. What you need is a middle ground: a way to configure an object step by step, then produce a fully validated result in one atomic operation.