โ Back to Design Patterns
๐จ
Creational
Builder
Constructs complex objects step by step using a fluent interface, separating construction from representation.
The Problem
A class with many optional parameters leads to telescoping constructors or long init calls that are hard to read. You need a clean way to build objects incrementally.
How It Works
- โบMethod chaining (fluent interface) makes construction readable
- โบSame builder can produce different representations
- โบValidates required fields only at build() time
- โบImmutable result: once built, the object is complete
- โบAvoids the "telescoping constructor" anti-pattern
When to Use
โObjects with many optional or configurable fields
โWhen the object requires multi-step construction
โWhen you want to create different configurations of the same object type
โHTTP request builders, query builders, notification payloads
Real-World Examples
๐
iOS
URLComponents, NSAttributedString, UIAlertController + addAction calls
๐ค
Android
AlertDialog.Builder, Notification.Builder, OkHttpClient.Builder
๐
Web
URLSearchParams, axios config, Knex/TypeORM query builders
Code Examples
Swift
struct PushPayload {
let title: String
let body: String
let badge: Int
let sound: String
let category: String?
}
final class PushPayloadBuilder {
private var title = ""
private var body = ""
private var badge = 0
private var sound = "default"
private var category: String?
func title(_ v: String) -> Self { title = v; return self }
func body(_ v: String) -> Self { body = v; return self }
func badge(_ v: Int) -> Self { badge = v; return self }
func sound(_ v: String) -> Self { sound = v; return self }
func category(_ v: String) -> Self { category = v; return self }
func build() -> PushPayload {
PushPayload(title: title, body: body, badge: badge,
sound: sound, category: category)
}
}
let payload = PushPayloadBuilder()
.title("New Message")
.body("You have 3 unread messages")
.badge(3)
.category("MESSAGE")
.build()