需求多维化拆分的防扩散设计原则
需求来了:“把’延期’从一类拆成三类(研发延期 / 测试延期 / 父任务延期)“。听起来就是加几个 if。但实际做下去,bug 一个接一个,过几天才陆续暴露。
这类 bug 的根因不在”代码写错”,而在改动的影响面没有被识别和控制。属于设计思路错误,不是编码错误。
为什么”1→N 拆分”是 bug 高发区
典型模式:
- 旧需求定义了一个单维度概念(“延期” = 看子任务 deadline)
- 新需求把它拆成多维度(“延期” = 研发延期 / 测试延期 / 父任务延期 三类)
- 拆分时没有重整架构,而是在每个消费点各自加分类判断
- 消费点散落在计算层、AI 层、导出层、前端 N 个页面
- 漏改 / 改错一处 → bug,且因边界场景才触发,往往上线几天后才被发现
同一个概念,N 个地方各写一遍分类逻辑,必然漂移。
五条防扩散设计原则
| # | 原则 | 踩坑表现 | 正确做法 |
|---|---|---|---|
| 1 | 单一数据源 | ”X 怎么算”在 N 个函数各写一遍,必然漂移 | 抽一个函数,所有页面/导出/AI 都调它,禁止重复实现同一计算 |
| 2 | 展示层与计算层分离 | 把分类标签混进了核心计算,逻辑纠缠 | 核心值先算出来;分类标签在最后渲染时再贴,计算层不感知分类 |
| 3 | 大改动先列影响面清单 | 改完等用户报 bug,才知道哪个页面漏了 | 维度拆分前先 grep 所有读该概念的地方,列成清单逐个验证 |
| 4 | 口径变更要带边界用例 | 没有测试,靠人工点页面 | 为每个分类写边界用例,测试驱动 |
| 5 | 同语义双实现要自动对齐 | 两个函数各算一遍没断言 → 必然漂移 | 加测试断言”同一对象在不同页面的统计值相等”,用测试守住一致性 |
启动三问(下次遇到”1→N 分类”需求时必问)
改之前先回答这三句,任何一句答不上来就先补设计、别急着写代码:
1. 计算层的单一数据源在哪? 这个概念的核心计算,是不是只有一个函数在算?如果 N 个地方各算一遍,先收口。
2. 分类能不能只活在展示层?
新增的维度能不能做成最后渲染时贴的标签,而不是侵入计算的 if?
3. 所有消费点是否都有测试覆盖? grep 出来的每个消费点,有没有对应的用例守着?漏改了能不能被测试抓住?
一个讽刺的真实现场
某系统”人数”这个统计被 3 处消费:顶部总览、部门卡、横向对比。某天领导要求”人数排除组长”——三处逐个改完。当天领导又改口”人数要含组长”(组长数据仍排除在工时/任务外,但人数含组长)——三处又得逐个改回。
如果当初抽了 group_member_count() 单一函数,这次翻转只改一个函数、所有页面自动同步。 朝令夕改在业务系统是常态,“一处改全同步”的价值正是在这种时候兑现。
什么时候必须建聚合函数层
不是所有项目都要做。涉及上万条级数据库记录 + 偏仪表盘 / 多页面对账的网页才需要——同一个统计口径被多个页面 / 接口 / 导出 / AI 同时消费时,立项阶段就要建统一聚合函数层,别等 bug 出来再补。
分层规范:
数据源 DB → 统一聚合函数(一个概念一个函数) → 后端算好派生字段(禁止把原始复合结构抛给消费端各自解读) → API 契约(字段字典,前端只读渲染,不做 len() 推导)加 跨页一致性断言测试 兜底:“同一对象在 A 页的统计 = B 页 = C 页”,后端改错立刻被抓,不用等用户报。
结论
需求多维化本身没错,错的是用”加 if”的方式去做架构级的改动。下次遇到”把 X 拆成几类”的需求,先停一下,回答启动三问——任何一个答不上来,先补设计。
改动的影响面必须被显式识别,不能靠”改完看看”兜底。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!







