low-complexity
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLow Complexity Code
低复杂度代码
Every function/method written or modified MUST target:
- Cognitive Complexity <= 5 (SonarSource metric). Acceptable up to 10 for inherently complex logic. Never exceed 15.
- Cyclomatic Complexity <= 5. Acceptable up to 10. Never exceed 15.
For full scoring rules, see cognitive-complexity-spec.md.
所有编写或修改的函数/方法必须满足以下目标:
- Cognitive Complexity <= 5(SonarSource 指标)。对于本身逻辑复杂的场景,可接受上限为10,但绝对不能超过15。
- Cyclomatic Complexity <= 5。可接受上限为10,绝对不能超过15。
完整评分规则请参考 cognitive-complexity-spec.md。
Cognitive Complexity Quick Reference
Cognitive Complexity 快速参考
+1 for each: , ternary (), (whole), , , , , , , , , each method in a recursion cycle, each sequence of like boolean operators ( / ).
if? :switchforwhiledo whilecatchelse ifelsegoto LABELbreak/continue LABEL&&||+1 nesting penalty on top of structural increment for: , ternary, , , , — when nested inside another flow-break structure.
ifswitchforwhilecatchFree (no increment): method calls, , , labels, null-coalescing (, ), early , simple /, lambdas (but lambdas increase nesting level).
tryfinallycase?.??returnbreakcontinue以下每种情况加1分: 、三元运算符()、(整个语句)、、、、、、、、、递归循环中的每个方法、连续的同类布尔运算符( / )。
if? :switchforwhiledo whilecatchelse ifelsegoto LABELbreak/continue LABEL&&||额外加1分嵌套惩罚(在结构加分基础上): 当、三元运算符、、、、嵌套在另一个流程中断结构内时。
ifswitchforwhilecatch不加分的情况: 方法调用、、、标签、空合并运算符(、)、提前、简单的/、lambda表达式(但lambda会增加嵌套层级)。
tryfinallycase?.??returnbreakcontinueCyclomatic Complexity Quick Reference
Cyclomatic Complexity 快速参考
+1 for the method entry, +1 for each: , , , , , , , , , ternary . Core definition; some analyzers may vary by language.
ifelse ifforwhiledo whilecasecatch&&||?方法入口加1分,以下每种情况加1分:、、、、、、、、、三元运算符。这是核心定义;部分分析工具可能因语言不同而有所差异。
ifelse ifforwhiledo whilecasecatch&&||?Mandatory Reduction Techniques
强制降低复杂度的技巧
Apply these in order of preference:
- Extract method/function — Move a coherent block into a named function. Resets nesting to 0. First choice when the extracted block forms a coherent unit.
- Early return / guard clause — Invert condition, return early, reduce nesting by 1 level.
- Replace nested conditions with flat logic — becomes
if A { if B {(saves nesting penalty).if A && B { - Replace if/else chains with polymorphism, strategy pattern, or lookup table — Eliminates branching entirely.
- Replace loop + condition with declarative pipeline — or LINQ or streams instead of
filter/map/reduce+for.if - Decompose boolean expressions — Extract complex conditions into named boolean variables or predicate functions.
- Replace flag variables with early exit — Eliminate boolean flags that control flow later.
- Use language idioms — Null-coalescing, optional chaining, pattern matching, destructuring. These are often lower-cost than equivalent if/else chains (destructuring is free; pattern matching is +1 for the whole match vs +1 per branch in if/else).
按优先级顺序应用以下技巧:
- Extract method/function — 将连贯的代码块移至一个命名函数中。将嵌套层级重置为0。当待提取的代码块构成一个连贯单元时,这是首选方案。
- Early return / guard clause — 反转条件,提前返回,将嵌套层级降低1级。
- Replace nested conditions with flat logic — 将改为
if A { if B {(避免嵌套惩罚)。if A && B { - Replace if/else chains with polymorphism, strategy pattern, or lookup table — 完全消除分支。
- Replace loop + condition with declarative pipeline — 使用、LINQ或流替代
filter/map/reduce+for。if - Decompose boolean expressions — 将复杂条件提取为命名布尔变量或谓词函数。
- Replace flag variables with early exit — 移除用于后续控制流程的布尔标志。
- Use language idioms — 使用空合并运算符、可选链、模式匹配、解构赋值。这些通常比等效的if/else链成本更低(解构赋值不加分;整个pattern matching语句加1分,而if/else每个分支加1分)。
How to Apply
应用方法
When writing any function/method:
- Write the logic
- Mentally count: each = +1, each nesting level on structural ones = +1 more, each boolean operator sequence = +1
if/else if/else/for/while/switch/catch/ternary - If score > 5, refactor using the techniques above before finalizing
- Prefer multiple small functions over one large function
- Nesting depth > 2 is a smell — extract immediately
编写任何函数/方法时:
- 编写逻辑代码
- 手动计算分数:每个加1分,结构语句的每个嵌套层级额外加1分,连续的布尔运算符加1分
if/else if/else/for/while/switch/catch/三元运算符 - 如果分数>5,在定稿前使用上述技巧进行重构
- 优先选择多个小函数,而非一个大函数
- 嵌套深度>2属于代码坏味道——立即进行提取重构
Bad vs Good Examples
反面示例 vs 正面示例
Bad: Nested conditionals (CogC = 9)
反面示例:嵌套条件语句(CogC = 9)
python
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 = 9python
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 = 9Good: Guard clauses + extraction (process CogC=2, charge CogC=2)
正面示例:守卫子句 + 提取重构(process 函数CogC=2,charge函数CogC=2)
python
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)python
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)Bad: Loop with nested conditions (CogC = 10)
反面示例:带嵌套条件的循环(CogC = 10)
javascript
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;
}javascript
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;
}Good: Flat filter + early continue (findFirst CogC=5, matches CogC=1)
正面示例:扁平化过滤 + 提前continue(findFirst 函数CogC=5,matches函数CogC=1)
javascript
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;
}javascript
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;
}