防错设计
1)目标与定义(一句话)
防错设计(error-proofing / poka-yoke)是把“犯错的可能性降到最低,并把不可避免的错误限制在可恢复或无害的范围内”的体系方法,目标包括预防、提示、自动纠正、快速恢复。
2)原则(核心思维)
- **以人为本**:假定人会犯错,设计以减少认知负担与歧义。
- **安全优先,体验为辅**:在关键安全/金钱/法律场景下优先保守。
- **可逆性(undo)**:优先支持撤销或补救。
- **可观测性**:发生错误时能快速定位原因与责任链。
- **最小惊讶原则**:系统行为应与用户期望一致。
- **自动化与人为校验并重**:自动拦截 + 人在环(必要时)组合使用。
3)扩展的防错类型(补充分类)
- **主动错误 vs 潜伏错误**:即时可察觉的交互错误 vs 系统隐蔽缺陷(race、config)。
- **偶发错误 vs 系统性错误**:单次操作失误 vs 设计/流程缺陷引发的大量错误。
- **用户端错误 vs 后端/运维错误**:输入/操作错误 vs 部署/数据库/网络错误。
4)犯错原因(更具体的心理/环境因素)
- 认知负载高(信息过多、步骤复杂)
- 语言/标签模糊(术语不一致)
- 反馈延迟或无反馈(用户看不到结果)
- 状态不一致(缓存/并发导致的脏读)
- 误导性默认值或自动化(隐性同意)
- 权限/角色不当(权限过大)
- 外部干扰(网络波动、焦虑、打断)
5)防错方法与设计模式(每项附简单范例)
断根(消除犯错的机会)
- **做法**:从交互上移除错误路径(灰化不可选项、禁用按钮)。
- **示例**:只有当表单必填都填写后才启用“提交”。
保险(多重确认 / 双人/多因素校验)
- **做法**:重要操作 require 二次确认 / 另一个人审批。
- **示例**:删除大量数据前弹确认并要求输入关键字确认;财务转账大额则需要二次审批。
自动(自动检测并阻断/恢复)
- **做法**:实时校验、自动回滚、幂等处理。
- **示例**:输入校验(手机号格式)、支付幂等 token、防止重复下单。
归一化(规范输入/状态)
- **做法**:把各种输入映射到标准格式,消除模糊。
- **示例**:统一时区、统一货币精度、输入自动 trim/normalize。
复制 / 冗余(冗余 + 备份)
- **做法**:关键数据多副本、事务日志、回滚点。
- **示例**:订单写入主库后备份到消息队列并异步落盘。
标识警告(及时可见的错误提示)
- **做法**:清晰、可操作的 inline error;提示要说明“如何修复”。
- **示例**:表单错误同时提示字段和原因(不是只显示“失败”)。
隔离(把错误限制在小范围)
- **做法**:沙箱、权限隔离、服务隔离。
- **示例**:实验功能放 feature flag、canary 发布,失败影响小流量。
顺序(引导与约束)
- **做法**:把复杂任务拆成可引导的步骤(分步表单),按顺序约束用户操作。
- **示例**:引导式安装/开户流程,每步校验并保存。
6)常用工程实践(软件/运维角度)
- **输入校验 + 格式化(前后端)**
- **幂等设计**(幂等 token、幂等 key)
- **事务与补偿事务**(SAGA / 事务回滚)
- **断路器 / 限流 / 重试策略(指数退避)**
- **Feature flags、蓝绿/金丝雀发布**
- **服务降级与兜底逻辑**
- **审计日志 + 可回放事件日志(event sourcing)**
- **自动化回滚 + 人工确认结合的部署 runbook**
7)评估与优先级(风险管理)
- 建表:`风险 = 发生概率 × 影响严重度`。
- 把风险分三类:**致命(必须阻断) / 严重(优先缓解) / 可接受(监控)**。
- 对每个风险写 “最坏可接受结果(MCA)” 和对应的补救措施(自动/人工)以及 SLA/MTTR 指标。
8)可执行的设计评审清单(设计/PR/上线前用)
- 这个操作的最坏后果是什么?能接受吗?
- 是否存在一次性不可逆操作?是否提供撤销?
- 是否有幂等/重复操作保护?
- UI 是否明确显示当前状态与下一个步骤?
- 是否存在隐式默认值?是否合理?
- 是否对关键路径做了自动校验?(前后端)
- 是否有监控/告警覆盖该场景?(错误率/回滚数)
- 是否有回滚/恢复的 runbook?是否演练过?
- 是否影响权限模型或数据隔离?
- 是否考虑了无障碍与国际化的错误信息?
9)测试 & 监控(确保防错措施有效)
- **测试**:单元测试覆盖校验逻辑、集成测试覆盖并发/重试场景、E2E 覆盖关键路径、混沌测试(Chaostesting)模拟网络/依赖失败。
- **监控**:错误率、重试次数、撤销(undo)使用率、回滚频率、MTTR、用户放弃率(drop-off)。
- **报警**:区分主动报警与观察性(trend)报警,避免告警疲劳。
10)文化与流程(组织层面)
- **鼓励上报与无责文化**(blameless postmortem)。
- **错误学习库**:把常见错误与对应的设计模式沉淀成 library/组件。
- **预案演练**:关键流程定期演练(恢复、回滚、手动补救)。
- **责任与权限清晰**:谁能执行高风险操作,谁能撤销。
11)常见误区(避免)
- 滥用确认弹窗(确认过多会被用户机械点击)
- 以“提示”代替“阻断”(提醒不等于防止)
- 把所有责任转给用户(让用户承担自动化应有的校验)
- 只关注前端,忽略后端并发/幂等问题
- 没有可测量的成功/失败指标
12)实战小模板(复用到 PRD / 设计文档)
场景:<短描述>目标用户:<谁>期望结果:<用户期望的最终状态>可能偏离路径(列举具体动作):1) … 2) …最坏后果(MCA):<能否接受?>优先级(高/中/低):建议防错措施(模式):1) … 2) …验收条件(测试/监控/告警):1) 单元/集成测试覆盖;2) 指标 < X;3) 回滚 runbook
13)举 3 个简短例子(帮助落地)
表单(提交地址/手机号)
- 做法:输入掩码 + 实时校验 + 智能默认 + 提交后提供“编辑/撤回 5 分钟”功能。
支付/下单
- 做法:幂等 token、防重复点击、支付前二次确认(金额/收款方)、失败后自动补偿或人工介入流程。
部署/配置变更
- 做法:feature flag + 金丝雀 + 自动回滚 + 明确的运维可执行 runbook。
14)度量指标(用于评估防错效果)
- 关键错误率(KR)
- 撤销(undo)使用率(高说明误操作多或撤销较易)
- 重试/回滚次数
- 平均恢复时间(MTTR)
- 用户放弃率(drop-off)或转化损失
- 自动修复覆盖率( %)
15)快速 10 项上线前核对清单(可打印)
- 有不可逆操作吗?有撤销或人工流程?
- 幂等/重复提交保护是否到位?
- 是否做了前后端一致性校验?
- 关键路径是否有监控与 SLO?
- 故障后能否快速回滚?有 runbook 吗?
- UI 有明确状态与错误修复提示吗?
- 是否考虑了权限与审计?
- 是否把“风险矩阵”写进 PRD?
- 是否做过并发/混沌/恢复测试?
- 是否记录了回退条件与沟通模版(对内/对外)?