
问题构造函数参数太多「伸缩构造」或步骤必须按顺序、且步骤组合多变。做法Director可选规定步骤顺序Builder提供setA()、setB()… 最后build()返回产品。C 要点很多场景用 fluent interface链式builder.withX().withY()提高可读性。若只是「很多默认可选参数」也可以先评估 默认成员 结构体选项 或 命名参数 idiomC 没有命名参数用小的struct Options很常见不必一上来上完整 Builder。// C17建造者Builder // 要点把复杂对象的构造拆成多步可读、可校验可与 Director 搭配固定几种装配顺序。 #include iostream #include memory #include optional #include sstream #include stdexcept #include string #include unordered_map #include utility // ---------- 产品字段多、组合多不适合巨型构造函数 ---------- class HttpRequest { public: const std::string url() const { return url_; } const std::string method() const { return method_; } const std::unordered_mapstd::string, std::string headers() const { return headers_; } const std::optionalstd::string body() const { return body_; } std::string describe() const { std::ostringstream os; os method_ url_ \n; for (const auto [k, v] : headers_) { os k : v \n; } if (body_.has_value()) { os [body] *body_ \n; } return os.str(); } private: friend class HttpRequestBuilder; HttpRequest() default; std::string url_; std::string method_{GET}; std::unordered_mapstd::string, std::string headers_; std::optionalstd::string body_; }; // ---------- 建造者流式 API最后 build() 一次性产出 ---------- class HttpRequestBuilder { public: HttpRequestBuilder set_url(std::string url) { url_ std::move(url); return *this; } HttpRequestBuilder set_method(std::string method) { method_ std::move(method); return *this; } HttpRequestBuilder add_header(std::string key, std::string value) { headers_.insert_or_assign(std::move(key), std::move(value)); return *this; } HttpRequestBuilder set_body(std::string body) { body_ std::move(body); return *this; } HttpRequest build() const { if (url_.empty()) { throw std::invalid_argument(HttpRequest: url 不能为空); } HttpRequest req; req.url_ url_; req.method_ method_; req.headers_ headers_; req.body_ body_; return req; } private: std::string url_; std::string method_{GET}; std::unordered_mapstd::string, std::string headers_; std::optionalstd::string body_; }; // ---------- Director可选封装常用装配流程 ---------- class ApiClientDirector { public: static HttpRequest simple_get(std::string url) { return HttpRequestBuilder{}.set_url(std::move(url)).build(); } static HttpRequest json_post(std::string url, std::string json) { return HttpRequestBuilder{} .set_url(std::move(url)) .set_method(POST) .add_header(Content-Type, application/json) .set_body(std::move(json)) .build(); } }; int main() { HttpRequest a HttpRequestBuilder{} .set_url(https://api.example.com/v1/users) .set_method(GET) .add_header(Accept, application/json) .add_header(Authorization, Bearer ***) .build(); std::cout 自定义 GET:\n a.describe() \n; HttpRequest b ApiClientDirector::json_post( https://api.example.com/v1/login, R({user:alice,pass:secret})); std::cout Director POST:\n b.describe() \n; try { (void)HttpRequestBuilder{}.build(); } catch (const std::exception ex) { std::cout 校验: ex.what() \n; } return 0; }