name: complexity-mitigator description: 缓解偶然代码复杂度,当控制流程纠缠、嵌套过深、名称难以解析或推理需要跨文件跳转时使用。在代码审查因可读性问题停滞、需要分析优先的重构计划再进行编辑,或需要获取本质与偶然性判断、排名简化步骤、小结构草图和TRACE评估(仅分析;不进行编辑)时使用。
复杂度缓解器
意图
减少偶然复杂性(理解成本),同时保留核心领域含义。
核心心态
- 保留本质复杂性,消除偶然性。
- 优先优化读者理解,其次提取。
- 最小切口,最大精度:仅更改能减少认知负荷的部分。
- 偏好无聊、本地清晰度而非聪明。
- 降低“理解成本”:减少需要记住的分支、跳转地点和模拟状态。
认知状态(启发式,非定律)
- 以下玩法是一组默认值,非保证。
- 没有通用证明表明任何单一动作总能减少复杂性;在本地验证。
- 当打破默认(例如,在展平前提取)时,说明原因(它解锁了什么)。
定义(本质 vs 偶然)
- 本质复杂性:领域规则、不变量、边界和必需的状态转换(简化它会改变正确行为或含义)。
- 偶然(偶然性)复杂性:由实现选择引入的复杂性(简化它保留行为并澄清意图)。
- 快速测试(不完美):如果读者必须心理执行代码以推断意图或允许状态,偶然复杂性可能隐藏了本质。例外:一些算法/并发需要真实模拟。
使用时机
- 代码审查因读者无法跟随流程而停滞。
- 在更改任何内容前需要解释代码在做什么(分析优先)。
- 看到深层嵌套(>3层是好的启发式)、长if/else链或重复分支。
- 进展需要跨文件跳转或模拟共享/可变状态。
保护措施
- 不进行文件编辑,不提交。
- 除非明确请求,不运行命令。
- 如果预期行为不清楚或产品敏感,停止并询问。
- 如果怀疑崩溃/损坏风险,推荐
$fix。
快速扫描(认知热读)
- 测量(粗略,非学术):
- 最大嵌套深度
- 分支计数(if/else/switch/三元)
- 布尔混乱计数(控制行为的布尔值/标志,尤其是组合)
- 跨文件跳转(必须打开以理解的独特定义)
- 需要模拟的状态(可变变量、隐式全局变量、顺序依赖)
- 用一行标注热点:
路径:行号 - [指标] - 为何困难。 - 标记每个热点:
本质(领域) vs偶然(实现) vs混合(领域被噪音隐藏)。 - 在提出更改前,将本质领域逻辑与偶然实现噪音分离。
- 将指标作为代理;不要优化数字如果它损害本地性或领域清晰度。
工作流程
- 选择切片:入口点、输入、输出、状态。
- 热读:命名热点及使其困难的原因。
- 跟踪行为(如果含义不清楚):快乐路径 + 关键失败路径;指出突变/IO。
- 判断:将本质领域逻辑与偶然实现噪音分离。
- 按顺序简化(默认):展平 -> 重命名 -> 提取(除非展平/重命名揭示稳定形状,否则不提取)。
- 选项:按努力与影响排名,并说明最小可行切割。
- 草图:展示改进的结构(类型 + 流程),非完整实现。
- TRACE:引用哪些字母被满足,哪些当前违反。
标准玩法(展平 -> 重命名 -> 提取)
- 展平:
- 使用保护子句和早期返回;保持快乐路径线性。
- 将嵌套条件拆分为独立路径(小助手或每路径独立函数);保持助手接近以避免额外跨文件跳转。
- 当顺序实质性影响正确性时,使时间耦合显式(状态机 / 显式步骤枚举)。
- 重命名:
- 用领域动作替换模糊动词(
process,handle,do);使名词与领域实体对齐。 - 修复布尔命名(偏好正面,避免双重否定);可能时消除布尔标志参数。
- 将含义移入数据:枚举 / 标签联合 / 选项对象优于多个布尔值(当它减少分支或无效状态时)。
- 用领域动作替换模糊动词(
- 提取(三原则):
- 拆分混合职责(解析 vs 验证 vs 决定 vs 效果)。
- 将重复分支转换为数据驱动调度(表格、处理程序映射、模式匹配)。
- 仅提取稳定、可重复概念;三原则是启发式(存在例外)。
选项排名标准
- 努力:微小(重命名/保护)、小(拆分函数)、中(引入枚举/表格)、大(模块边界 / 状态机)。
- 影响:减少分支、减少跨文件跳转、减少模拟状态、澄清不变量。
什么算作证据(本地,非全局)
- 偏好本地、可检查证据而非全局声明。
- 可能时使用前后指标:
- 嵌套/分支/标志/跳转/模拟状态(来自热读)
- 哪些不变量变得显式(类型/构造函数/断言/测试)
- 接受哪些权衡(例如,更多函数以换取线性流程)
输出格式
0) 切片
- 入口点: …
- 输入/输出/状态: …
1) 热读(热点)
路径:行号- …
1.5) 行为跟踪(可选)
- 快乐路径: …
- 失败路径: …
- 突变/IO: …
2) 本质 vs 偶然
- 本质: …
- 偶然: …
3) 选项(按努力 vs 影响排名)
- 最小可行切割: …
- …
- …
4) 草图
// 最小示意片段
5) TRACE
- 满足: …(你的推荐结构改进的字母)
- 违反: …(当前代码失败的字母)
为什么TRACE是复杂度缓解的一部分
- 在此技能中,将“复杂性”主要视为理解成本(非性能或操作复杂性)。
- TRACE是防止虚假简化并使权衡显式的透镜:
- T(类型):可以从考虑中移除无效状态;过度建模也可能增加噪音。
- R(可读性):减少命名/结构摩擦,感觉像复杂性。
- A(原子性):分离决定与执行;混合职责常创建偶然复杂性。
- C(认知性):直接针对嵌套/分支/状态模拟。
- E(本质性):检查你是在删除实现噪音,非删除领域含义。
- 使用TRACE使缓解结果可检查:“哪些理解成本下降,以及哪些被权衡?”
TRACE快速参考
- T(类型):无效状态不可表示;约束存在于类型/构造函数中(保持类型模型最小)。
- R(可读性):意图从名称和本地性显而易见。
- A(原子性):每单元单一职责;决定与效果分离(避免逻辑分散在太多小单元)。
- C(认知性):低嵌套/分支;最小状态模拟。
- E(本质性):代码仅表达领域必需的复杂性。
不变量指导
当缺少不变量阻止简化时使用。
- 请求或推断:状态转换、允许/禁止状态、所有权/不可变性、错误处理边界。
- 识别解锁展平的最小不变量(例如,“状态X暗示Y”)。
- 如果不变量未知,推荐添加断言或在类型中使其显式。
易错清单
当混淆API或命名导致误用时使用。
- 隐藏副作用或状态全局变量
- 不明显前提条件或顺序依赖
- 布尔参数意义反转
- 沉默默认值或魔法值
- 不同概念的相似名称
- 不一致或隐式的错误处理
升级
- 如果出现重复代数形状或可组合管道,考虑切换到通用主义技能并构建最小代数 + 定律。
- 如果用户想要实现,升级到
$fix。