关于 low-complexity
面向开发者的编码技能,为函数和方法设定认知复杂度与圈复杂度目标。它提供复杂度计算指引、按优先级排列的重构方法,以及减少分支和嵌套的示例。
主要功能
- 01设定函数复杂度目标
- 02计算认知复杂度与圈复杂度
- 03通过提取和守卫子句重构
- 04减少嵌套与分支
- 05运用语言惯用写法
适用场景
- 01审查复杂函数
- 02重构深层嵌套逻辑
- 03为代码变更设定复杂度规范
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mryll/ skills --skill low-complexity安装后在 Claude Code 中输入/low-complexity确认已加载。
附带文件references/cognitive-complexity-spec.md
详细介绍
低复杂度代码
编写或修改的每个函数/方法都必须达到以下要求:
- 认知复杂度 <= 5(SonarSource 指标)。对于逻辑本身复杂的情况,可接受最高 10。绝不能超过 15。
- 圈复杂度 <= 5。可接受最高 10。绝不能超过 15。
完整评分规则请参阅 cognitive-complexity-spec.md。
认知复杂度速查
以下各项分别 +1: if、三元表达式(? :)、switch(整体)、for、while、do while、catch、else if、else、goto LABEL、break/continue LABEL、递归循环中的每个方法,以及每组连续的同类布尔运算符(&& / ||)。
嵌套惩罚 +1: 以下结构位于另一种流程中断结构内时,在结构增量的基础上额外 +1:if、三元表达式、switch、for、while、catch。
不增加复杂度: 方法调用、try、finally、case 标签、空值合并(?.、??)、提前 return、简单的 break/continue、lambda(但 lambda 会增加嵌套层级)。
圈复杂度速查
方法入口 +1,以下各项分别 +1:if、else if、for、while、do while、case、catch、&&、||、三元表达式 ?。这是核心定义;不同语言的分析器可能有所差异。
必须采用的降低复杂度技巧
按以下优先顺序应用:
- 提取方法/函数 — 将逻辑完整的代码块移到一个命名函数中。嵌套层级重置为 0。当提取的代码块构成一个完整单元时,优先采用此方法。
- 提前返回 / 守卫子句 — 反转条件并提前返回,减少一层嵌套。
- 将嵌套条件改为扁平逻辑 — 将
if A { if B {改为if A && B {(减少嵌套惩罚)。 - 用多态、策略模式或查找表替代 if/else 链 — 完全消除分支。
- 用声明式管道替代循环 + 条件 — 使用
filter/map/reduce、LINQ 或流式操作,替代for+if。 - 拆分布尔表达式 — 将复杂条件提取为命名布尔变量或谓词函数。
- 用提前退出替代标志变量 — 消除用于控制后续流程的布尔标志。
- 使用语言惯用写法 — 空值合并、可选链、模式匹配、解构。这些写法的成本通常低于等效的 if/else 链(解构不增加复杂度;模式匹配整体 +1,而 if/else 中每个分支都 +1)。
应用方法
编写任何函数/方法时:
- 编写逻辑
- 在脑海中计数:每个
if/else if/else/for/while/switch/catch/三元表达式= +1;结构嵌套的每一层再 +1;每组布尔运算符序列 +1 - 如果得分 > 5,完成前使用上述技巧重构
- 优先使用多个小函数,而非一个大函数
- 嵌套深度 > 2 是一种警示,应立即提取代码
错误与正确示例
错误:嵌套条件(认知复杂度 = 9)
def process(user, order):
if user.is_active: # +1
if order.is_valid: # +2 (nesting=1)
if order.total > 100: # +3 (nesting=2)
apply_discount(order)
else: # +1
charge_full(order)
else: # +1
raise InvalidOrder()
else: # +1
raise InactiveUser() # Total: 1+2+3+1+1+1 = 9
正确:守卫子句 + 提取(process 认知复杂度 = 2,charge 认知复杂度 = 2)
def process(user, order): # CogC = 2
if not user.is_active: # +1
raise InactiveUser()
if not order.is_valid: # +1
raise InvalidOrder()
charge(order)
def charge(order): # CogC = 2
if order.total > 100: # +1
apply_discount(order)
else: # +1
charge_full(order)
错误:包含嵌套条件的循环(认知复杂度 = 10)
function findFirst(items, criteria) {
for (const item of items) { // +1
if (item.active) { // +2 (nesting=1)
if (item.type === criteria.type) { // +3 (nesting=2)
if (item.score > criteria.min) { // +4 (nesting=3)
return item;
}
}
}
} // Total: 1+2+3+4 = 10
return null;
}
正确:扁平化过滤 + 提前 continue(findFirst 认知复杂度 = 5,matches 认知复杂度 = 1)
function findFirst(items, criteria) { // CogC = 5
for (const item of items) { // +1
if (!item.active) continue; // +2 (nesting=1)
if (matches(item, criteria)) return item; // +2 (nesting=1)
}
return null;
}
function matches(item, criteria) { // CogC = 1
return item.type === criteria.type // +1 (&& sequence)
&& item.score > criteria.min;
}
评论
支持 Markdown