文档目录

一、什么时候用?

场景:构造一个对象需要十几个参数,有些必填、有些可选、有些有依赖关系:

// ❌ 构造函数方式——十几个参数,调用者分不清谁是谁
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 创建。