Design Patterns
Creational Patterns
Patterns that decouple how an object is constructed from the code that uses it — so callers depend on an interface or abstract type, never on which concrete class actually gets instantiated.
- Factory Method: a subclass decides which concrete class to instantiate, exposed through a method the base class defines but doesn't implement
- Abstract Factory: a factory that produces a family of related objects guaranteed to work together (e.g. a UI theme's button + checkbox + scrollbar)
- Builder: separates constructing a complex object step-by-step from representing it — avoids telescoping constructors with many optional parameters
- Singleton: guarantees exactly one instance of a class exists, with a single global access point — the most misused pattern in the catalog
- Prototype: creates new objects by cloning an existing configured instance rather than constructing from scratch
| Pattern | Use when | Java idiom |
|---|---|---|
| Factory Method | a class can't know which concrete subtype to create ahead of time | a create() method overridden per subclass |
| Abstract Factory | you need a family of related objects that must match | a factory interface with one method per product |
| Builder | a constructor would need many optional/ordered parameters | fluent Builder class with chained setters + build() |
| Singleton | exactly one instance must exist app-wide | an enum with one constant (safest form in Java) |
| Prototype | creating from scratch is expensive; cloning a template is cheap | clone() or a copy constructor |
public final class HttpRequest {
private final String url;
private final String method;
private final Map<String, String> headers;
private HttpRequest(Builder b) {
this.url = b.url; this.method = b.method; this.headers = b.headers;
}
public static class Builder {
private final String url;
private String method = "GET";
private final Map<String, String> headers = new HashMap<>();
public Builder(String url) { this.url = url; }
public Builder method(String m) { this.method = m; return this; }
public Builder header(String k, String v) { headers.put(k, v); return this; }
public HttpRequest build() { return new HttpRequest(this); }
}
}
HttpRequest req = new HttpRequest.Builder("https://api.example.com")
.method("POST")
.header("Content-Type", "application/json")
.build();