一个需求拆成八个任务,八个都在看板上"进行中",上线日期仍然只有一个——全部做完的那天。这不是拆,是把一件事的名字抄了八遍。
切分只有一个判据:拆完之后能不能更早把一小块交到用户手里,并从那一小块学到点东西。 做不到的拆分只是把风险摊进八个盒子,再把协调成本乘以八。
1. 判断动机:缩短反馈,还是分派工作
| 动机 | 形态 | 提前暴露的风险 | 代价 |
|---|---|---|---|
| 分派工作 | 按人拆、按层拆、按模块拆 | 几乎没有,风险集中到整合 | 协调成本、接口返工 |
| 缩短反馈 | 每个切片能被看见或被使用 | 假设错误、方案不可行 | 切片重叠、重复劳动 |
十分钟自检:首个切片能否在整体完工前产生"用户可见"或"决策可用"的效果? 能,是缩短反馈;不能,只是分派工作。
只有第一种动机却叫"敏捷拆分",会出一个隐蔽后果:完成度成为唯一可信的数(八件做了七件 = 87.5%),可交付价值是零。第二个约束是评审者的注意力:首切片三周后才有人看,切得再小也没变快。
// 开拆前四问,任一答不出就先别拆
1. 首切片上线后,谁用、看到什么变化?
2. 谁能一周内给出"成立/不成立"?
3. 撤回去要动几处、要不要修数据?
2. 三种切分维度与适用条件
维度不是偏好,是约束。选错维度,切片间立刻出现"必须同时上线"的死结。
| 维度 | 切法 | 适用条件 | 失效信号 |
|---|---|---|---|
| 按用户路径 | 先支持一条角色或一条业务流 | 使用者可分开、分支清晰 | 路径共享状态,互相污染 |
| 按数据范围 | 先覆盖一部分数据(租户、区域、品类) | 有天然键可隔离且语义不变 | 余额、库存、额度等一致性要求 |
| 按能力层次 | 先只做查询、成功路径,不做批量 | 对用户的承诺能拆开讲 | 把"部分能力"当"全部能力" |
三条结论:按用户路径切最安全,用户是天然隔离边界;按数据范围切最容易撞一致性,金额、库存、配额分开要维护两套账;按能力层次切最容易骗自己。混进来的第四种是按服务切,几乎总是分派工作。
3. 纵向切片与横向分层
纵向切片从入口穿到存储,把"用户做一件事"走通;横向分层先做完整一层(全部接口与表结构),再做下一层。
| 对比项 | 纵向切片 | 横向分层 |
|---|---|---|
| 单切片可运行性 | 端到端能点能测 | 每层能编译,拼不成一件事 |
| 首个可用产物 | 早 | 晚,最后一层完成才算 |
| 纠错成本 | 低,改一条链路 | 高,要回改所有已完成层 |
| 典型失败 | 切片间重复实现公共逻辑 | 全部编译通过,没有一样能用 |
后果:所有验证被推到唯一的集成点,那里同时有 n 个未验证假设,失败无法归因。归因不了的失败只会重演一轮,一轮又是三周。
横向分层有一处正当用途:技术可行性不确定时做只回答一个问题的探针("这个数据量下查询能否进 200ms")。探针须可丢弃;一旦长出 DTO、Controller、文档,它就是那个永远不上线的地基。
4. 可独立交付的四条判据
| 判据 | 通过标准 | 不通过的表现 |
|---|---|---|
| 有用户可见变化 | 有人(哪怕内部角色)能感知差异 | 只有日志和表结构变了 |
| 可独立回滚 | 撤掉它,其余功能照常 | 要同时撤三处,或需要修数据 |
| 不依赖未完成切片 | 依赖已上线能力或已有降级路径 | "等 B 那件做完就能演示" |
| 有自己的验收方式 | 含成功判据与失败判据 | 验收标准是"功能跑通" |
第二条最易被忽略:回滚取决于 schema 是否向前兼容、是否写了新数据——只要写进新字段的值,revert 代码不会把数据还回来。第四条决定信息价值。
// slice.yaml ── 申报表,评审时对着念
slice: order-partial-refund
visible_to: [客服角色] // 用户可见范围
rollback: flag partial_refund // 开关 / revert / 双写
depends_on: [] // 只允许列已上线项
5. 最小可用切片能小到什么程度
切分容易滑向另一极端:小到连假设都验证不了——它仍可交付、可回滚、有可见变化,但验证的是"代码能跑"。
| 切片内容 | 可交付 | 验证假设 | 说明 |
|---|---|---|---|
| 完整退款(手工备付金通道) | 是 | 是 | 小但闭环 |
| 表单 + 后台无处理入口 | 是 | 否 | 用户给的是投诉,不是反馈 |
| 只读的进度查询 | 是 | 是 | 验证用户是否在意进度 |
| 全量逻辑 + 90% 分支不可用 | 否 | 否 | 未完成的整体,不是切片 |
判据:能让至少一个真实用户完成一件事;成本显著低于它可能推翻的东西。为验证"要不要"先做完整链路,假设被推翻时损失已经发生。
6. 不切比切便宜:四类硬约束
| 硬约束 | 为什么不能切 | 可行做法 |
|---|---|---|
| 数据迁移 | 新旧两份并存,双写窗口本身就是风险期 | 整体设计、按批执行 |
| 权限变更 | 一半人走新鉴权时,越权与误拒同时出现 | 灰度名单 → 切权限源 → 清理 |
| 对外承诺 | "部分支持"在客户那里等于"不支持" | 整体交付,或提前锁范围并确认 |
| 资金幂等改造 | 中间态会两边都记或都不记 | 加幂等键 → 切调用 → 清旧路径 |
更隐蔽的是证据链:合规动作要求完整、可举证、一次性,拆成三个切片等于交付三份不完整的证据。
7. 顺序依赖怎么表达
依赖不要停在"先做 A 再做 B"的口头约定,要变成可检查的东西:
// 1) 弱:只存在于会议纪要
S1 → S2 → S3
// 2) 中:写进申报表,依赖"已上线"而非"已合入"
S2.depends_on: [S1.上线]
// 3) 强:数据/契约层不可交换
S2 读 S1 写入的 ledger_id;S1 未上线 → 无输入
关键是依赖已上线而不是已合入——中间有灰度、观察、可能回滚的窗口。另一条纪律:依赖链不超过两跳,三件串行说明首切片太窄。
8. 技术前置切片:必要与滥用
技术前置指业务切片前先做的部分:拆服务、建索引、改表、引缓存、搭观测。
| 判据 | 例子 | 结论 |
|---|---|---|
| 有当前阻塞的上线目标 | 不建索引首版查询必然超时 | 可做,绑定具体切片 |
| 完成状态可观测 | P99 从秒级降到毫秒级 | 可做 |
| 只服务"以后会用到" | 没有指名的第一个消费者 | 最小版本,或不做 |
| 不可回滚、不可停机 | 大表结构变更 | 独立排期与演练 |
失控形态很稳定:网关、消息、配置、灰度平台陆续做完,理由都正当,业务上线数量却没变。问题不在技术判断,在于每个前置都没绑定交付对象——地基建好,业务切片还不知在哪,就该停止投入。
// pre-slice.yaml ── 前置片段准入条件
pre_slice: 订单表 ledger_id 索引
blocks: S1 订单查询切片 // 必须点名它阻塞谁
observable: P99 < 300ms // 可测的完成状态
9. 粒度与团队规模、发布频率
| 团队规模 | 发布频率 | 合适粒度 | 失控后果 |
|---|---|---|---|
| 1–3 人 | 随时可发 | 半天到两天 | 切太细,写入与验收成本超收益 |
| 4–8 人 | 按发布窗口 | 2–5 天,一窗装 2–3 个 | 批次成本高于切分收益 |
| 8 人以上、多团队 | 每天多次 | 一天内,按人分不按层分 | 排队、协调、冲突成为主要成本 |
10. 切片与估时
经验现象很稳:估时超过五天的工作项,通常意味着没切好——时间越长未知越多,估算越接近主观概率。
| 估时 | 判断 | 应对 |
|---|---|---|
| ≤ 1 天 | 可信 | 直接做 |
| 2–5 天 | 可信,但验收模糊 | 强制写失败判据 |
| 6–10 天 | 含 1–2 个未知 | 探针砍掉未知再估 |
| > 10 天 | 偏差通常 2 倍以上 | 不排期,先切分 |
要区分的是估时短但反复延期——不是概率问题,是切片不独立,估时不含等待,而等待就是延期的全部来源。
// 估时前的过滤:任一命中就不给日期
depends_on 含未上线项 → 先拆
估时 > 5 天 → 找出 1 个未知,做 1 天探针
11. 度量
| 指标 | 口径 | 读到什么 | 反噬 |
|---|---|---|---|
| 平均切片大小 | 交付用时中位数 | 是否真的在变小 | 强切 → 失去可验证性 |
| 切片到上线时长 | 首次可交付 → 上线 | 流程问题,不是切分 | 无 |
| 返工率 | 上线后被推翻的占比 | 切分假设是否成立 | 与需求变动混淆 |
| 首切片延迟 | 受理 → 首切片上线 | 反馈周期是否缩短 | 被"切得极小"骗过 |
配对读法:切片变小 + 首切片延迟下降 + 返工率不上升才算有效。
12. 排错
| 现象 | 可能原因 | 验证 |
|---|---|---|
| 看板满绿,什么都没上线 | 按层拆,集成点在最后 | 有任一任务能独立演示? |
| 切片都"快了",总周期没变 | 依赖串行,等待被转移 | 看关键路径是否唯一 |
| 首切片上线用户没察觉 | 不具备可感知变化 | 问真实用户能否说出差异 |
| 每次评审都要重讲上下文 | 切片不按语义切 | 名称能否一句话讲清谁做什么 |
13. 边界
| 场景 | 为什么不划算 | 替代 |
|---|---|---|
| 需求本身小于一天 | 记录与评审成本超过收益 | 直接做,用提交说明当记录 |
| 纯探索性任务 | 该切的是问题,不是交付物 | 设时间盒与判据 |
| 不可分割的合规动作 | 中间态不构成有效证据 | 可拆部分放准备阶段 |
还有一条不显眼的:上线本身很贵时,切分收益会被上线成本吃掉——每次要停机、审批、客户协调,切小只会让上线次数变多。
14. 自测
- 十分钟内怎么判断一个八任务拆分是"真切分"还是"分派工作"?
- 按数据范围切分时,哪类数据会让首个切片就撞上一致性死结?
- 横向分层在什么条件下正当?它的正确形态要满足哪几点?
- 涉写路径时,"可独立回滚"为什么不能只靠代码 revert?
- 一个切片验证假设的最低条件是什么?举一个"有界面但没信息"的反例。
- 依赖链出现三跳以上时,先改什么、不先改什么?