组合模式是将具层级关系的配置项建模为树形结构,通过统一接口(如getValue、validate、toJson)管理整体与部分,Leaf负责终端值校验,Composite负责递归委托,实现操作透明化与扩展无缝化。

变量的组合设计模式不是指“变量本身被组合”,而是把具有层级关系的配置项、参数对象或可配置实体建模为树形结构,用统一接口管理它们——比如系统中的一组配置:全局配置(根)、模块配置(分支)、具体字段(叶子),它们都支持“获取值”“校验”“序列化”等操作。
明确哪些变量适合组成树结构
不是所有变量都需要组合模式。适用前提是存在清晰的“整体-部分”归属关系,且需统一操作。例如:
- 前端表单配置:表单(Composite)→ 分组区块(Composite)→ 输入框/下拉框(Leaf)
- 后端服务参数:服务实例(Composite)→ 数据库连接池(Composite)→ 最大连接数/超时时间(Leaf)
- 实验平台参数集:实验模板(Composite)→ 算法模块(Composite)→ 学习率/迭代次数(Leaf)
关键判断点:这些变量是否会被批量读取、递归校验、统一导出,或动态增删子项?如果是,就具备组合模式的应用基础。
定义统一的操作接口(Component)
不写具体类,先定契约。接口至少包含三类能力:
-
行为方法:如
getValue()、validate()、toJson()—— 所有节点都必须实现 -
结构方法:如
addChild()、removeChild()、getChildren()—— 只在 Composite 中有实际逻辑,Leaf 可抛不支持异常或空实现 -
元信息方法:如
getName()、getPath()(如"db.pool.maxActive"),便于日志和调试
避免让 Leaf 实现 addChild 这类无意义方法;更推荐在接口中只声明行为方法,结构方法单独抽成 Container 接口由 Composite 实现,提升类型安全。
区分 Leaf 和 Composite 的职责边界
Leaf 是终端数据载体,不持有子项:
- 它封装一个原始值(string/number/boolean)或简单对象(如 { min: 0, max: 100 })
- 它的
validate()直接校验自身值(如非空、范围检查) - 它的
toJson()返回字面量,不带 children 字段
Composite 是容器,负责编排与委托:
- 它持有一个
List或 Map,管理子节点 - 它的
validate()遍历所有子项并聚合结果(如全部通过才返回 true) - 它的
toJson()返回含children字段的对象,递归调用每个子项的toJson()
例如:一个 “HTTP 超时配置” Composite 包含 “连接超时” Leaf 和 “读取超时” Leaf;调用该 Composite 的 validate(),自动触发两个 Leaf 的校验,无需客户端循环。
客户端代码保持简洁透明
使用者不需要判断类型,直接对任意节点调用统一方法:
// 无论 config 是 ServerConfig(Composite)还是 TimeoutMs(Leaf) config.validate(); // 自动走对应逻辑 config.toJson(); // 自动产出嵌套或扁平结构
新增一种配置类型(比如加个 “重试策略” Composite)时,只要实现 Component 接口,就能无缝接入现有校验、导出、UI 渲染流程,不用改调用方代码。
这种一致性,正是组合模式在变量管理中真正解决的问题:让层级结构“消失”在接口背后,让操作回归语义本身。










