一、什么时候用?
场景:构造一个对象需要十几个参数,有些必填、有些可选、有些有依赖关系:
// ❌ 构造函数方式——十几个参数,调用者分不清谁是谁
HttpRequest req("POST", "http://api.example.com/data",
10000, // timeout
true, // keepalive
"gzip", // encoding
...);
// ✅ Builder 方式——逐步设置,可读性强
HttpRequest req = HttpRequest::Builder()
.method("POST")
.url("http://api.example.com/data")
.timeout(10000)
.keepalive(true)
.encoding("gzip")
.build();
二、Builder 的现代 C++ 写法
class HttpRequest {
public:
class Builder {
std::string method_ = "GET";
std::string url_;
int timeout_ = 5000;
bool keepalive_ = true;
std::string encoding_ = "utf-8";
public:
Builder& method(std::string m) { method_ = std::move(m); return *this; }
Builder& url(std::string u) { url_ = std::move(u); return *this; }
Builder& timeout(int t) { timeout_ = t; return *this; }
// [[nodiscard]] 防止调用者忘了调用 build()
[[nodiscard]] HttpRequest build() {
// 可以在 build 时做参数校验
if (url_.empty()) throw std::invalid_argument("url required");
return HttpRequest(std::move(method_), std::move(url_),
timeout_, keepalive_, std::move(encoding_));
}
};
private:
HttpRequest(std::string method, std::string url, int timeout,
bool keepalive, std::string encoding)
: method_(std::move(method)), url_(std::move(url)),
timeout_(timeout), keepalive_(keepalive), encoding_(std::move(encoding)) {}
};
关键:Builder 只是中间媒介,build() 才真正构造对象。构造函数的参数可以是 private 的,强制用户通过 Builder 创建。