Sync Factory Method, Abstract Factory, Builder, Prototype to Java 25; fix post/code mismatches
This commit is contained in:
76
01-creational/builder/HttpRequest.java
Normal file
76
01-creational/builder/HttpRequest.java
Normal file
@@ -0,0 +1,76 @@
|
||||
package builder;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class HttpRequest {
|
||||
|
||||
// All fields are final: the object is immutable after build() returns.
|
||||
private final String url;
|
||||
private final String method;
|
||||
private final String body;
|
||||
private final Map<String, String> headers;
|
||||
private final int timeoutMs;
|
||||
private final int maxRetries;
|
||||
|
||||
// Private: the only path to an HttpRequest is through Builder.build()
|
||||
private HttpRequest(Builder builder) {
|
||||
this.url = Objects.requireNonNull(builder.url, "URL is required");
|
||||
this.method = builder.method;
|
||||
this.body = builder.body;
|
||||
this.headers = Collections.unmodifiableMap(new HashMap<>(builder.headers));
|
||||
this.timeoutMs = builder.timeoutMs;
|
||||
this.maxRetries = builder.maxRetries;
|
||||
}
|
||||
|
||||
// Getters only — no setters, enforcing immutability
|
||||
public String getUrl() { return url; }
|
||||
public String getMethod() { return method; }
|
||||
public String getBody() { return body; }
|
||||
public Map<String, String> getHeaders() { return headers; }
|
||||
public int getTimeoutMs() { return timeoutMs; }
|
||||
public int getMaxRetries() { return maxRetries; }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s %s (timeout=%dms, retries=%d, headers=%s, body=%s)",
|
||||
method, url, timeoutMs, maxRetries, headers, body);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// THE BUILDER — static inner class so it can call the private constructor
|
||||
// -----------------------------------------------------------------------
|
||||
public static class Builder {
|
||||
|
||||
// Required field — no default, must be set
|
||||
private String url;
|
||||
|
||||
// Optional fields with sensible defaults
|
||||
private String method = "GET";
|
||||
private String body = null;
|
||||
private Map<String, String> headers = new HashMap<>();
|
||||
private int timeoutMs = 30_000; // 30 seconds
|
||||
private int maxRetries = 0;
|
||||
|
||||
// Fluent methods: each returns 'this' so calls can be chained
|
||||
public Builder url(String url) { this.url = url; return this; }
|
||||
public Builder method(String method) { this.method = method; return this; }
|
||||
public Builder body(String body) { this.body = body; return this; }
|
||||
public Builder header(String key, String v) { headers.put(key, v); return this; }
|
||||
public Builder timeoutMs(int ms) { this.timeoutMs = ms; return this; }
|
||||
public Builder maxRetries(int n) { this.maxRetries = n; return this; }
|
||||
|
||||
// Terminal method: validates and creates the immutable HttpRequest
|
||||
public HttpRequest build() {
|
||||
if (url == null || url.isBlank()) {
|
||||
throw new IllegalStateException("url() is required before calling build()");
|
||||
}
|
||||
if (maxRetries < 0) {
|
||||
throw new IllegalStateException("maxRetries must be >= 0");
|
||||
}
|
||||
return new HttpRequest(this); // calls the private constructor
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user