Builder Pattern¶
Category: Creational Pattern
Overview¶
Separate the construction of a complex object from its representation, allowing the same construction process to create different representations. This pattern provides a step-by-step approach to constructing objects, particularly useful when objects require many configuration parameters or complex initialization.
Usage Guidelines¶
Use when:
- Object creation involves many steps or configuration options
- Same construction process should create different representations
- Many optional parameters would lead to multiple constructors
- Building immutable objects step by step before finalization
Avoid when:
- Object has few parameters and simple construction
- Object always created the same way
- Builder adds unacceptable performance overhead
- Python dataclasses or named tuples work well
Implementation¶
from __future__ import annotations
class Computer:
"""Represents a computer with various components.
This is the product class that the builder constructs.
"""
def __init__(self) -> None:
"""Initialize an empty computer."""
self.cpu: str | None = None
self.ram: int | None = None
self.storage: str | None = None
self.gpu: str | None = None
self.os: str | None = None
self.peripherals: list[str] = []
def get_specifications(self) -> str:
"""Get the computer specifications as a formatted string.
Returns:
A string representation of the computer specifications.
"""
specs = []
if self.cpu:
specs.append(f"CPU: {self.cpu}")
if self.ram:
specs.append(f"RAM: {self.ram}GB")
if self.storage:
specs.append(f"Storage: {self.storage}")
if self.gpu:
specs.append(f"GPU: {self.gpu}")
if self.os:
specs.append(f"OS: {self.os}")
if self.peripherals:
specs.append(f"Peripherals: {', '.join(self.peripherals)}")
return "\n".join(specs) if specs else "No specifications set"
class ComputerBuilder:
"""Builder for constructing Computer objects.
This builder uses method chaining (fluent interface) to set component properties.
"""
def __init__(self) -> None:
"""Initialize the builder with a new Computer instance."""
self._computer = Computer()
def set_cpu(self, cpu: str) -> ComputerBuilder:
"""Set the CPU.
Args:
cpu: The CPU model.
Returns:
The builder instance for method chaining.
"""
self._computer.cpu = cpu
return self
def set_ram(self, ram: int) -> ComputerBuilder:
"""Set the RAM amount in GB.
Args:
ram: The RAM size in gigabytes.
Returns:
The builder instance for method chaining.
"""
self._computer.ram = ram
return self
def set_storage(self, storage: str) -> ComputerBuilder:
"""Set the storage configuration.
Args:
storage: The storage description.
Returns:
The builder instance for method chaining.
"""
self._computer.storage = storage
return self
def set_gpu(self, gpu: str) -> ComputerBuilder:
"""Set the GPU.
Args:
gpu: The GPU model.
Returns:
The builder instance for method chaining.
"""
self._computer.gpu = gpu
return self
def set_os(self, os: str) -> ComputerBuilder:
"""Set the operating system.
Args:
os: The operating system name.
Returns:
The builder instance for method chaining.
"""
self._computer.os = os
return self
def add_peripheral(self, peripheral: str) -> ComputerBuilder:
"""Add a peripheral device.
Args:
peripheral: The peripheral name.
Returns:
The builder instance for method chaining.
"""
self._computer.peripherals.append(peripheral)
return self
def build(self) -> Computer:
"""Build and return the configured Computer instance.
Returns:
The fully constructed Computer instance.
"""
return self._computer
def reset(self) -> ComputerBuilder:
"""Reset the builder to start building a new computer.
Returns:
The builder instance with a new Computer.
"""
self._computer = Computer()
return self
Usage¶
# Building a custom computer
builder = ComputerBuilder()
computer = (builder
.set_cpu("Intel i9")
.set_ram(32)
.set_storage("1TB SSD")
.set_gpu("NVIDIA RTX 4090")
.set_os("Windows 11")
.add_peripheral("Mechanical Keyboard")
.add_peripheral("Gaming Mouse")
.build())
print(computer.get_specifications())
# Output:
# CPU: Intel i9
# RAM: 32GB
# Storage: 1TB SSD
# GPU: NVIDIA RTX 4090
# OS: Windows 11
# Peripherals: Mechanical Keyboard, Gaming Mouse
Trade-offs¶
Benefits:
- Readable code through fluent interface that is self-documenting
- Step-by-step construction of complex objects incrementally
- Same builder can create different product variants
- Can construct immutable objects piece by piece
Drawbacks:
- Adds extra classes and code, increasing complexity
- Builder methods may duplicate product setters
- Creates intermediate objects during construction
- Product may be in invalid state during construction
Real-World Examples¶
- SQL query builders constructing complex queries
- HTTP request builders with headers, body, parameters
- Document builders creating documents with sections
- Test data builders with various configurations
Related Patterns¶
- Abstract Factory
- Composite
- Prototype
- Singleton
- Fluent Interface
API Reference¶
design_patterns.creational.builder
¶
Builder Pattern Module
The Builder pattern separates the construction of a complex object from its representation, allowing the same construction process to create different representations. It is particularly useful when an object requires many configuration parameters or when the construction process involves multiple steps.
Example
Building a computer with various components:
Computer
¶
Represents a computer with various components.
This is the product class that the builder constructs.
Source code in src/design_patterns/creational/builder.py
__init__()
¶
Initialize an empty computer.
Source code in src/design_patterns/creational/builder.py
get_specifications()
¶
Get the computer specifications as a formatted string.
Returns:
| Type | Description |
|---|---|
str
|
A string representation of the computer specifications. |
Source code in src/design_patterns/creational/builder.py
ComputerBuilder
¶
Builder for constructing Computer objects.
This builder uses method chaining (fluent interface) to set component properties.
Source code in src/design_patterns/creational/builder.py
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | |
__init__()
¶
add_peripheral(peripheral)
¶
Add a peripheral device.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
peripheral
|
str
|
The peripheral name. |
required |
Returns:
| Type | Description |
|---|---|
ComputerBuilder
|
The builder instance for method chaining. |
Source code in src/design_patterns/creational/builder.py
build()
¶
Build and return the configured Computer instance.
Returns:
| Type | Description |
|---|---|
Computer
|
The fully constructed Computer instance. |
reset()
¶
Reset the builder to start building a new computer.
Returns:
| Type | Description |
|---|---|
ComputerBuilder
|
The builder instance with a new Computer. |
set_cpu(cpu)
¶
Set the CPU.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cpu
|
str
|
The CPU model. |
required |
Returns:
| Type | Description |
|---|---|
ComputerBuilder
|
The builder instance for method chaining. |
set_gpu(gpu)
¶
Set the GPU.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gpu
|
str
|
The GPU model. |
required |
Returns:
| Type | Description |
|---|---|
ComputerBuilder
|
The builder instance for method chaining. |
set_os(os)
¶
Set the operating system.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
os
|
str
|
The operating system name. |
required |
Returns:
| Type | Description |
|---|---|
ComputerBuilder
|
The builder instance for method chaining. |
Source code in src/design_patterns/creational/builder.py
set_ram(ram)
¶
Set the RAM amount in GB.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ram
|
int
|
The RAM size in gigabytes. |
required |
Returns:
| Type | Description |
|---|---|
ComputerBuilder
|
The builder instance for method chaining. |
set_storage(storage)
¶
Set the storage configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
storage
|
str
|
The storage description. |
required |
Returns:
| Type | Description |
|---|---|
ComputerBuilder
|
The builder instance for method chaining. |
Source code in src/design_patterns/creational/builder.py
House
¶
Represents a house with various features.
This demonstrates an alternative product for the builder pattern.
Source code in src/design_patterns/creational/builder.py
__init__()
¶
Initialize an empty house.
Source code in src/design_patterns/creational/builder.py
describe()
¶
Get a description of the house.
Returns:
| Type | Description |
|---|---|
str
|
A string describing the house features. |
Source code in src/design_patterns/creational/builder.py
HouseBuilder
¶
Builder for constructing House objects.
This demonstrates director methods that encapsulate common build configurations.
Source code in src/design_patterns/creational/builder.py
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | |
__init__()
¶
add_garage()
¶
Add a garage to the house.
Returns:
| Type | Description |
|---|---|
HouseBuilder
|
The builder instance for method chaining. |
add_garden()
¶
Add a garden to the house.
Returns:
| Type | Description |
|---|---|
HouseBuilder
|
The builder instance for method chaining. |
build()
¶
Build and return the configured House instance.
Returns:
| Type | Description |
|---|---|
House
|
The fully constructed House instance. |
build_luxury_house()
¶
Build a luxury house with premium features.
This is a director method that encapsulates a premium configuration.
Returns:
| Type | Description |
|---|---|
House
|
A luxury house. |
Source code in src/design_patterns/creational/builder.py
build_simple_house()
¶
Build a simple house with basic features.
This is a director method that encapsulates a common configuration.
Returns:
| Type | Description |
|---|---|
House
|
A simple house. |
Source code in src/design_patterns/creational/builder.py
set_doors(count)
¶
Set the number of doors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
count
|
int
|
Number of doors. |
required |
Returns:
| Type | Description |
|---|---|
HouseBuilder
|
The builder instance for method chaining. |
set_foundation(foundation)
¶
Set the foundation type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
foundation
|
str
|
The foundation type. |
required |
Returns:
| Type | Description |
|---|---|
HouseBuilder
|
The builder instance for method chaining. |
Source code in src/design_patterns/creational/builder.py
set_roof(roof)
¶
Set the roof type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
roof
|
str
|
The roof type. |
required |
Returns:
| Type | Description |
|---|---|
HouseBuilder
|
The builder instance for method chaining. |
set_walls(walls)
¶
Set the wall material.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
walls
|
str
|
The wall material. |
required |
Returns:
| Type | Description |
|---|---|
HouseBuilder
|
The builder instance for method chaining. |
set_windows(count)
¶
Set the number of windows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
count
|
int
|
Number of windows. |
required |
Returns:
| Type | Description |
|---|---|
HouseBuilder
|
The builder instance for method chaining. |