建造者模式专为参数组合不可控、必填/可选边界模糊而设计;其核心是将完整性校验前置到build(),强制私有构造、链式赋值无副作用、语义分组复合方法、build()唯一校验并创建不可变对象。
建造者模式不是为“参数多”而存在,而是为“参数组合不可控 + 必填/可选边界模糊”而设计。当一个业务对象有十几个甚至几十个字段,其中部分必填、部分有条件生效、部分互斥或依赖另一字段时,直接用构造函数或 setter 链都会导致调用混乱、状态不一致、校验滞后等问题。builder 的核心价值,在于把对象完整性校验从运行时提前到 build() 调用那一刻,并让必填约束在代码流中自然浮现。
必须封死构造入口,只留 Builder 入口
Product 类(如 Email、ServerConfig)的构造函数必须是 private,且只接受 Builder 实例或其内部结构(如数组)作为唯一参数。不能暴露 public 构造器,否则绕过 Builder 直接 new 就会破坏契约。同时,静态工厂方法(如 Email::create())必须返回 Builder 实例,而不是 Product 或中间态对象。这是保证构建过程受控的第一道防线。
链式方法只赋值、不执行副作用
所有 setXxx() 方法必须满足两个条件:
- 仅做属性赋值,返回 $this,支持连续调用
- 不触发任何外部操作(如 DNS 查询、连接测试、远程鉴权)
比如 setHost() 只存字符串,enableTLS() 只标记开关;真实校验和初始化动作应交给 build() 或后续独立的 validate() / connect() 方法完成。
按语义分组 + 提供快捷复合方法
面对三十多个字段,平铺 setXxx() 会让 IDE 补全失效、阅读成本陡增。真实配置天然分层:
- 网络层:host、port、timeout、tlsEnabled
- 认证层:token、secret、region、scope
- 行为层:retryTimes、maxConns、autoFlush
- 日志层:logLevel、traceId、samplingRate
应在 Builder 中提供 withNetwork()、withAuth()、withRetry() 等复合方法,内部封装多个原子 set 调用,既提升可读性,也便于未来统一调整逻辑。
build() 是唯一校验点,也是对象诞生时刻
build() 方法承担三重责任:
- 检查必填字段是否已设置(如 host、token 缺一不可)
- 验证字段间依赖关系(如 timeout > 0 仅当 tlsEnabled === true)
- 一次性将所有参数传入 Product 私有构造器,生成不可变对象
不在此处做远程有效性检查(如 API key 是否真实可用),那是业务层职责,不属于构建阶段。校验失败应抛出 InvalidArgumentException,而非静默降级或默认填充。










