因为配置项多、有依赖、需校验且环境差异大,建造者模式可分离构造与表示,确保不可变性、复用模板、链式设置;set_*方法应即时校验,build()只返回纯数据类实例并补默认值,避免耗时操作和外部依赖。

为什么不用直接传参或字典初始化配置对象
因为配置项多、有依赖关系、部分字段需校验、不同环境(dev/staging/prod)模板差异大。硬编码 dict 或长参数列表会让调用方耦合校验逻辑,且新增字段时所有调用点都要改。建造者模式把「构造过程」和「表示」分离,让配置对象不可变、可复用模板、支持链式设置。
Builder 类必须封装校验和默认值逻辑
很多实现只做属性赋值,结果运行时才报错。正确做法是在 set_timeout、set_host 等方法里立刻检查合法性:
-
set_timeout(self, seconds: int)应抛出ValueError当seconds -
set_host(self, host: str)应拒绝空字符串或非法域名格式(可用urllib.parse.urlparse快速验证) - 所有非必填字段应在
__init__中设为None,并在build()中统一补默认值(如timeout=30、retries=3)
避免在 build() 里做耗时操作
建造者不是工厂,不负责实例化外部资源。常见错误是把连接数据库、读取远程 YAML 配置的逻辑塞进 build() —— 这会让构建过程不可预测、难测试、无法缓存。正确边界是:
-
build()只返回纯数据类(dataclass或NamedTuple)实例 - 如果需要从文件加载基础配置,应由外部传入
base_config: dict,建造者只做覆盖和增强 - 若需兼容旧版配置键名(如
"max_retry"→"retries"),转换逻辑放__init__或单独的from_legacy()类方法,别混进build()
用 __post_init__ 替代手动校验更安全
如果用 @dataclass 定义最终配置类,把字段校验移到 __post_init__ 比在每个 set_* 方法里重复判断更可靠 —— 它能兜底所有构造路径(包括未来可能加的其他 builder 变体)。示例:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
立即学习“Python免费学习笔记(深入)”;
@dataclass(frozen=True)
class Config:
host: str
timeout: int
retries: int = 3
<pre class='brush:python;toolbar:false;'>def __post_init__(self):
if not self.host or ":" in self.host: # 简单域名检查
raise ValueError("host must be non-empty and not contain ':'")
if self.timeout < 1:
raise ValueError("timeout must be >= 1")注意:此时建造者的 build() 方法只需传参给 Config(...),校验交给 __post_init__ 自动触发。
复杂校验(如 timeout * retries )仍建议放在 <code>build() 里显式检查,避免把业务约束埋进数据类。

















