mcpField
L
low-complexity

low-complexity

github.com/mryll开发652 次安装2 周前更新
代码仓库

关于 low-complexity

面向开发者的编码技能,为函数和方法设定认知复杂度与圈复杂度目标。它提供复杂度计算指引、按优先级排列的重构方法,以及减少分支和嵌套的示例。

主要功能

  1. 01设定函数复杂度目标
  2. 02计算认知复杂度与圈复杂度
  3. 03通过提取和守卫子句重构
  4. 04减少嵌套与分支
  5. 05运用语言惯用写法

适用场景

  1. 01审查复杂函数
  2. 02重构深层嵌套逻辑
  3. 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、&&、||、三元表达式 ?。这是核心定义;不同语言的分析器可能有所差异。

必须采用的降低复杂度技巧

按以下优先顺序应用:

  1. 提取方法/函数 — 将逻辑完整的代码块移到一个命名函数中。嵌套层级重置为 0。当提取的代码块构成一个完整单元时,优先采用此方法。
  2. 提前返回 / 守卫子句 — 反转条件并提前返回,减少一层嵌套。
  3. 将嵌套条件改为扁平逻辑 — 将 if A { if B { 改为 if A && B {(减少嵌套惩罚)。
  4. 用多态、策略模式或查找表替代 if/else 链 — 完全消除分支。
  5. 用声明式管道替代循环 + 条件 — 使用 filter/map/reduce、LINQ 或流式操作,替代 for + if。
  6. 拆分布尔表达式 — 将复杂条件提取为命名布尔变量或谓词函数。
  7. 用提前退出替代标志变量 — 消除用于控制后续流程的布尔标志。
  8. 使用语言惯用写法 — 空值合并、可选链、模式匹配、解构。这些写法的成本通常低于等效的 if/else 链(解构不增加复杂度;模式匹配整体 +1,而 if/else 中每个分支都 +1)。

应用方法

编写任何函数/方法时:

  1. 编写逻辑
  2. 在脑海中计数:每个 if/else if/else/for/while/switch/catch/三元表达式 = +1;结构嵌套的每一层再 +1;每组布尔运算符序列 +1
  3. 如果得分 > 5,完成前使用上述技巧重构
  4. 优先使用多个小函数,而非一个大函数
  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