codeprobe-code-smells

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Standalone Mode

独立模式

If invoked directly (not via the orchestrator), you must first:
  1. Read
    ../codeprobe/shared-preamble.md
    for the output contract, execution modes, and constraints.
  2. Load applicable reference files from
    ../codeprobe/references/
    based on the project's tech stack.
  3. Default to
    full
    mode unless the user specifies otherwise.
如果直接调用(不通过编排器),您必须先执行以下步骤:
  1. 阅读
    ../codeprobe/shared-preamble.md
    文件,了解输出约定、执行模式和约束条件。
  2. 根据项目的技术栈,从
    ../codeprobe/references/
    目录加载适用的参考文件。
  3. 除非用户另有指定,否则默认使用
    full
    模式。

Code Smells & Anti-Pattern Detector

Code Smells & Anti-Patterns 检测器

Domain Scope

领域范围

This sub-skill detects code smells and anti-patterns organized into these categories:
  1. Bloaters — Long Method, Large Class, Data Clumps, Primitive Obsession
  2. Object-Orientation Abusers — Feature Envy, Inappropriate Intimacy, Refused Bequest
  3. Change Preventers — Shotgun Surgery, Divergent Change
  4. Dispensables — Dead Code, Speculative Generality, Middle Man
  5. Couplers — Temporal Coupling
  6. Readability — Magic Numbers, Boolean Blindness, Deep Nesting

该子技能检测以下分类的code smells和anti-patterns:
  1. Bloaters — Long Method、Large Class、Data Clumps、Primitive Obsession
  2. Object-Orientation Abusers — Feature Envy、Inappropriate Intimacy、Refused Bequest
  3. Change Preventers — Shotgun Surgery、Divergent Change
  4. Dispensables — Dead Code、Speculative Generality、Middle Man
  5. Couplers — Temporal Coupling
  6. Readability — Magic Numbers、Boolean Blindness、Deep Nesting

What It Does NOT Flag

不会标记的内容

  • Generated code — Migrations, compiled output, vendor directories (
    vendor/
    ,
    node_modules/
    ,
    dist/
    ,
    build/
    ,
    .next/
    ), and auto-generated files (e.g., GraphQL codegen, Prisma client).
  • Test files with long setup methods — Test context is different; long
    setUp()
    or
    beforeEach()
    methods arranging test data are expected and acceptable.
  • Configuration files with many entries — A config file with 50 key-value pairs is not a "Large Class" smell.
  • Data migration files — These are procedural by nature and often contain long methods.
  • Third-party code checked into the repository (e.g., vendored libraries).
  • Structural issues already flagged by
    codeprobe-solid
    or
    codeprobe-architecture
    — Large classes may also be flagged as SRP violations or god objects. This sub-skill should still detect and report them, but the orchestrator will deduplicate overlapping findings at the same location.

  • 生成代码 — 迁移文件、编译输出、供应商目录(
    vendor/
    node_modules/
    dist/
    build/
    .next/
    )以及自动生成的文件(例如GraphQL codegen、Prisma client)。
  • 测试文件中的长初始化方法 — 测试上下文不同,用于安排测试数据的长
    setUp()
    beforeEach()
    方法是符合预期且可接受的。
  • 配置文件中的大量条目 — 包含50个键值对的配置文件不属于“Large Class”异味。
  • 数据迁移文件 — 这类文件本质上是过程式的,通常包含长方法。
  • 签入仓库的第三方代码(例如供应商库)。
  • 已被
    codeprobe-solid
    codeprobe-architecture
    标记的结构性问题
    — 大类可能同时被标记为SRP违规或上帝对象。该子技能仍需检测并报告这些问题,但编排器会对同一位置的重复发现进行去重。

Detection Instructions

检测说明

Configurable Thresholds

可配置阈值

Before analysis, check for a
.codeprobe-config.json
file in the project root. If present, load the
severity_overrides
section to adjust these defaults:
ThresholdConfig KeyDefault
Long Method LOC limit
long_method_loc
30
Large Class LOC limit
large_class_loc
300
Deep Nesting max levels
deep_nesting_max
3
分析前,请检查项目根目录下是否存在
.codeprobe-config.json
文件。若存在,加载
severity_overrides
部分以调整以下默认值:
阈值配置键默认值
Long Method LOC限制
long_method_loc
30
Large Class LOC限制
large_class_loc
300
深层嵌套最大层级
deep_nesting_max
3

Bloaters

Bloaters

ID PrefixSmellSignalHow to DetectDefault ThresholdSeverity
SMELL
Long MethodFunction/method exceeds LOC thresholdCount lines in each function/method body (excluding blank lines and single-line comments). Compare against
long_method_loc
threshold. For methods 2x over threshold, escalate to major.
> 30 LOCMinor
SMELL
Large ClassClass exceeds LOC thresholdCount total lines in each class definition. Compare against
large_class_loc
threshold. For classes 2x over threshold, escalate to major (if not already major). Never escalate to critical — large classes are a maintainability concern, not a production defect.
> 300 LOCMajor
SMELL
Data ClumpsSame 3+ params passed together in 3+ placesSearch for function/method signatures. Identify groups of 3+ parameters that appear together in 3+ different function signatures or call sites. These should be extracted into a parameter object or value object.3+ params, 3+ occurrencesMinor
SMELL
Primitive ObsessionString/int used where a value object is warrantedLook for string/integer variables representing domain concepts: email addresses (validated by regex inline), money amounts (numeric + currency passed separately), phone numbers, status strings compared in multiple places, ZIP codes, UUIDs passed as plain strings through multiple layers.Pattern recognitionMinor
ID前缀异味类型信号检测方式默认阈值严重程度
SMELL
Long Method函数/方法超出LOC阈值统计每个函数/方法体的行数(不包括空行和单行注释),与
long_method_loc
阈值对比。若方法行数超过阈值的2倍,升级为Major级别。
> 30 LOCMinor
SMELL
Large Class类超出LOC阈值统计每个类定义的总行数,与
large_class_loc
阈值对比。若类行数超过阈值的2倍,升级为Major级别(若尚未是Major)。永远不要升级为Critical级别——大类是可维护性问题,而非生产缺陷。
> 300 LOCMajor
SMELL
Data Clumps相同的3个及以上参数在3个及以上位置一起传递搜索函数/方法签名,识别出现在3个及以上不同函数签名或调用位置的3个及以上参数组。这些参数应提取为参数对象或值对象。3+参数,3+出现次数Minor
SMELL
Primitive Obsession使用字符串/整数代替值对象查找代表领域概念的字符串/整数变量:通过内联正则验证的电子邮件地址、单独传递的金额(数值+货币)、电话号码、在多个位置比较的状态字符串、邮政编码、作为纯字符串在多层传递的UUID。模式识别Minor

Object-Orientation Abusers

Object-Orientation Abusers

ID PrefixSmellSignalHow to DetectDefault ThresholdSeverity
SMELL
Feature EnvyMethod accesses another object's data 3x+ more than its ownCount how many times a method references
$other->property
or
other.property
versus
$this->property
or
this.property
(or
self.
). If external references outnumber internal ones by 3x or more, the method likely belongs in the other class.
3+ external accessesMinor
SMELL
Inappropriate IntimacyClass accessing another's private/protected internalsSearch for reflection-based access (
setAccessible(true)
,
__get
,
__set
magic methods accessing protected fields), friend class patterns, or direct access to properties that are conventionally private (prefixed with
_
in Python/JS).
Any occurrenceMajor
SMELL
Refused BequestSubclass inherits but doesn't use most of parent's methodsExamine subclasses: if the parent has N public methods and the subclass overrides fewer than 30% of them while also not calling
super
/
parent::
for most, this suggests the subclass doesn't truly need the inheritance relationship.
Unused majority of parent methodsMinor
ID前缀异味类型信号检测方式默认阈值严重程度
SMELL
Feature Envy方法访问另一个对象的数据次数是自身的3倍及以上统计方法引用
$other->property
other.property
的次数,与引用
$this->property
this.property
(或
self.
)的次数对比。若外部引用次数是内部引用的3倍及以上,该方法可能属于另一个类。
3+外部访问Minor
SMELL
Inappropriate Intimacy类访问另一个类的私有/受保护内部成员搜索基于反射的访问(
setAccessible(true)
__get
__set
魔术方法访问受保护字段)、友元类模式,或直接访问通常为私有的属性(Python/JS中以下划线
_
开头)。
任何出现情况Major
SMELL
Refused Bequest子类继承但未使用父类的大部分方法检查子类:若父类有N个公共方法,子类重写的方法不足30%,且大部分方法未调用
super
/
parent::
,则表明子类并非真正需要继承关系。
未使用父类的大部分方法Minor

Change Preventers

Change Preventers

ID PrefixSmellSignalHow to DetectDefault ThresholdSeverity
SMELL
Shotgun SurgeryChanging one concept requires edits in 5+ filesSearch for a single concept (e.g., a field name, a status value, a business rule) that appears across many files. If the same constant, column name, or business term appears in 5+ files without being centralized behind a single source of truth, flag it.5+ files for one conceptMajor
SMELL
Divergent ChangeOne class modified for 3+ unrelated reasonsExamine large classes (> 200 LOC). Check whether the methods cluster around distinct, unrelated concerns. If a single class handles user authentication, email formatting, AND report generation, it has divergent change — any of those 3 areas changing forces this class to change.3+ distinct concernsMajor
ID前缀异味类型信号检测方式默认阈值严重程度
SMELL
Shotgun Surgery修改一个概念需要编辑5个及以上文件搜索出现在多个文件中的单一概念(例如字段名、状态值、业务规则)。若同一常量、列名或业务术语出现在5个及以上文件中,且未集中在单一数据源背后,则标记该问题。一个概念涉及5+文件Major
SMELL
Divergent Change一个类因3个及以上无关原因被修改检查大类(>200 LOC),查看方法是否围绕不同的无关关注点聚类。若单个类同时处理用户认证、邮件格式和报告生成,则存在Divergent Change——这些3个领域中的任何一个发生变化,都会导致该类需要修改。3+不同关注点Major

Dispensables

Dispensables

ID PrefixSmellSignalHow to DetectDefault ThresholdSeverity
SMELL
Dead CodeUnreachable branches, unused imports, commented-out code blocksSearch for: (1)
import
/
use
/
require
statements for symbols never referenced elsewhere in the file, (2) commented-out code blocks (3+ consecutive commented lines that contain code syntax, not documentation), (3) functions/methods never called from anywhere in the codebase (use Grep across the project), (4)
if (false)
or
if (0)
blocks, unreachable code after unconditional
return
/
throw
/
exit
.
Any occurrenceMinor
SMELL
Speculative GeneralityAbstractions/interfaces with only one implementation and no foreseeable secondSearch for interfaces, abstract classes, or generic type parameters that have exactly one concrete implementation. If the abstraction does not appear in a DI container config or test mock, and the domain doesn't suggest future variants, flag it as premature abstraction.Single implementationSuggestion
SMELL
Middle ManClass that only delegates to another class with no added logicLook for classes where every method simply calls the same method on an injected dependency and returns the result, with no added logic, validation, transformation, or error handling. The class adds an unnecessary indirection layer.Pure delegation in all methodsMinor
ID前缀异味类型信号检测方式默认阈值严重程度
SMELL
Dead Code不可达分支、未使用的导入、注释掉的代码块搜索:(1) 文件中从未被引用的
import
/
use
/
require
语句;(2) 注释掉的代码块(3行及以上连续注释,包含代码语法而非文档);(3) 代码库中从未被调用的函数/方法(在项目中使用Grep搜索);(4)
if (false)
if (0)
块、无条件
return
/
throw
/
exit
后的不可达代码。
任何出现情况Minor
SMELL
Speculative Generality只有一个实现且预计不会有第二个实现的抽象/接口搜索只有一个具体实现的接口、抽象类或泛型类型参数。若该抽象未出现在DI容器配置或测试模拟中,且领域不暗示未来会有变体,则标记为过早抽象。单一实现Suggestion
SMELL
Middle Man仅委托给另一个类且无额外逻辑的类查找所有方法仅调用注入依赖的相同方法并返回结果,且无额外逻辑、验证、转换或错误处理的类。该类添加了不必要的间接层。所有方法均为纯委托Minor

Couplers

Couplers

ID PrefixSmellSignalHow to DetectDefault ThresholdSeverity
SMELL
Temporal CouplingMethods must be called in specific order but nothing enforces itLook for patterns where: (1) method A must be called before method B but there's no compile-time or runtime check, (2)
init()
/
setup()
must be called before
process()
but the class allows
process()
to be called first, (3) sequential method calls with shared mutable state where reordering would cause bugs. Check for comments like "must call X first" or "call after Y".
Implicit ordering dependencyMajor
ID前缀异味类型信号检测方式默认阈值严重程度
SMELL
Temporal Coupling方法必须按特定顺序调用但无任何强制机制查找以下模式:(1) 方法A必须在方法B之前调用,但无编译时或运行时检查;(2)
init()
/
setup()
必须在
process()
之前调用,但类允许先调用
process()
;(3) 共享可变状态的顺序方法调用,重排顺序会导致错误。检查类似“必须先调用X”或“在Y之后调用”的注释。
隐式顺序依赖Major

Readability

Readability

ID PrefixSmellSignalHow to DetectDefault ThresholdSeverity
SMELL
Magic NumbersHardcoded numeric/string literals without named constants in business logicSearch for numeric literals (other than 0, 1, -1) and string literals used in conditionals, calculations, or business logic. Flag values like
86400
,
3.14159
,
"pending"
,
0.15
that appear in logic paths without a named constant. Exclude: array indices, loop bounds of 0/1, common math constants in math libraries.
Any in logic pathsMinor
SMELL
Boolean BlindnessMethod with 2+ boolean paramsSearch for function/method signatures with 2 or more
bool
/
boolean
parameters. Call sites like
process(true, false, true)
are unreadable. Suggest using named parameters, enums, or option objects instead.
2+ boolean parametersMinor
SMELL
Deep NestingIndentation levels exceed thresholdCount nesting depth in each function: each
if
,
for
,
while
,
foreach
,
switch
,
try
,
match
that is nested inside another adds a level. Flag when nesting exceeds
deep_nesting_max
threshold. Suggest early returns, guard clauses, or method extraction.
> 3 levelsMinor

ID前缀异味类型信号检测方式默认阈值严重程度
SMELL
Magic Numbers业务逻辑中使用未命名常量的硬编码数值/字符串字面量搜索条件判断、计算或业务逻辑中使用的数值字面量(0、1、-1除外)和字符串字面量。标记出现在逻辑路径中且无命名常量的值,如
86400
3.14159
"pending"
0.15
。排除:数组索引、0/1的循环边界、数学库中的常见数学常量。
逻辑路径中的任何出现情况Minor
SMELL
Boolean Blindness包含2个及以上布尔参数的方法搜索包含2个及以上
bool
/
boolean
参数的函数/方法签名。像
process(true, false, true)
这样的调用位置可读性差。建议使用命名参数、枚举或选项对象替代。
2+布尔参数Minor
SMELL
Deep Nesting缩进层级超过阈值统计每个函数的嵌套深度:每个嵌套在其他结构中的
if
for
while
foreach
switch
try
match
都会增加一层。当嵌套超过
deep_nesting_max
阈值时标记。建议使用提前返回、守卫子句或方法提取。
>3层级Minor

ID Prefix & Fix Prompt Examples

ID前缀与修复提示示例

All findings use the
SMELL-
prefix, numbered sequentially:
SMELL-001
,
SMELL-002
, etc.
所有发现均使用
SMELL-
前缀,并按顺序编号:
SMELL-001
SMELL-002
等。

Fix Prompt Examples

修复提示示例

  • "Extract lines 45-90 of
    UserService@register
    into a private method
    validateAndNormalizeInput()
    — the method is 120 LOC doing 3 unrelated things: input validation (lines 45-65), data normalization (lines 66-80), and persistence (lines 81-90). Keep persistence in
    register()
    and extract the other two concerns."
  • "Replace the magic number
    86400
    at line 55 of
    app/Services/CacheService.php
    with a named constant
    SECONDS_PER_DAY = 86400
    defined at the top of the class."
  • "Refactor
    processOrder(bool $isExpress, bool $requiresSignature, bool $isFragile)
    in
    OrderProcessor.php
    (line 30) to accept a
    ShippingOptions
    value object instead of 3 boolean parameters. Create a
    ShippingOptions
    class with named properties."
  • "Remove the commented-out code block at lines 88-105 of
    PaymentGateway.php
    — this is dead code from a previous implementation. If needed later, it can be recovered from version control."
  • "In
    ReportGenerator.php
    , the
    generate()
    method at line 20 is 95 LOC. Extract the data-fetching logic (lines 25-50) into
    fetchReportData()
    and the formatting logic (lines 51-85) into
    formatReport()
    . The
    generate()
    method should orchestrate these two steps."
  • "将
    UserService@register
    的第45-90行提取为私有方法
    validateAndNormalizeInput()
    ——该方法有120 LOC,处理3项无关事务:输入验证(第45-65行)、数据标准化(第66-80行)和持久化(第81-90行)。将持久化逻辑保留在
    register()
    中,提取另外两项逻辑。"
  • "将
    app/Services/CacheService.php
    第55行的魔术数字
    86400
    替换为类顶部定义的命名常量
    SECONDS_PER_DAY = 86400
    。"
  • "重构
    OrderProcessor.php
    第30行的
    processOrder(bool $isExpress, bool $requiresSignature, bool $isFragile)
    ,使其接受
    ShippingOptions
    值对象而非3个布尔参数。创建带有命名属性的
    ShippingOptions
    类。"
  • "移除
    PaymentGateway.php
    第88-105行的注释代码块——这是旧实现的死代码。若后续需要,可从版本控制系统恢复。"
  • "在
    ReportGenerator.php
    中,第20行的
    generate()
    方法有95 LOC。将数据获取逻辑(第25-50行)提取到
    fetchReportData()
    ,将格式化逻辑(第51-85行)提取到
    formatReport()
    generate()
    方法应协调这两个步骤。"