Builder (Creational)
Intent / problem it solves
Separate construction of a complex object from its representation, allowing step-by-step assembly and varying configurations (required vs optional fields, fluent APIs).
When to use / when NOT
Use when many optional parameters exist, invariants span multiple fields, or you want readable construction (fluent builder).
Avoid when a constructor or small factory covers all cases, or when immutability plus a plain struct literal is enough.
Structure
Director (optional) orchestrates builder steps; concrete builders accumulate state and return the product.
Go example
package main
import "fmt"
type Query struct {
table string
columns []string
limit int
}
type QueryBuilder struct{ query Query }
func NewQueryBuilder() *QueryBuilder { return &QueryBuilder{} }
func (builder *QueryBuilder) From(table string) *QueryBuilder {
builder.query.table = table
return builder
}
func (builder *QueryBuilder) Select(columns ...string) *QueryBuilder {
builder.query.columns = columns
return builder
}
func (builder *QueryBuilder) Limit(limit int) *QueryBuilder {
builder.query.limit = limit
return builder
}
func (builder *QueryBuilder) Build() Query { return builder.query }
func main() {
query := NewQueryBuilder().From("orders").Select("id", "total").Limit(10).Build()
fmt.Println(query)
}JavaScript example
class HttpRequest {
constructor({ method, url, headers, body }) {
this.method = method;
this.url = url;
this.headers = headers;
this.body = body;
}
}
class HttpRequestBuilder {
constructor() {
this.method = 'GET';
this.url = '';
this.headers = {};
this.body = null;
}
setMethod(method) {
this.method = method;
return this;
}
setUrl(url) {
this.url = url;
return this;
}
setHeader(name, value) {
this.headers[name] = value;
return this;
}
setBody(body) {
this.body = body;
return this;
}
build() {
return new HttpRequest({
method: this.method,
url: this.url,
headers: { ...this.headers },
body: this.body,
});
}
}
const request = new HttpRequestBuilder()
.setMethod('POST')
.setUrl('/api/orders')
.setHeader('content-type', 'application/json')
.setBody({ amount: 42 })
.build();
console.log(request.method, request.body);Interview phrase
“Builder keeps complex construction readable and validates invariants before returning the object; I use it for requests, configs, and test data where optional fields explode.”
Related LLD case studies
Map to LLD for request builders, report pipelines, or menu / DSL construction in LLD case studies.
Last updated on
Spotted something unclear or wrong on this page?