mcpField
C
code-smell-detector

code-smell-detector

github.com/rysweet测试与质量76250 次安装21 周前更新
代码仓库

关于 code-smell-detector

面向使用 amplihack 的开发者的代码审查技能,可识别违背简洁与模块化原则的代码结构,并给出具体重构步骤。

主要功能

  1. 01识别多余抽象与复杂继承
  2. 02发现超长函数和紧密耦合
  3. 03检查 Python 模块是否缺少 __all__ 导出
  4. 04通过示例说明问题并提供重构步骤

适用场景

  1. 01合并前审查代码
  2. 02重构时寻找简化机会
  3. 03检查新模块是否符合 amplihack 原则

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rysweet/amplihack --skill code-smell-detector

安装后在 Claude Code 中输入/code-smell-detector确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

QUICK_START.md
README.md
examples/
smell_analysis_example.md

详细介绍

代码异味检测技能

用途

此技能用于识别违反 amplihack 开发理念的反模式,并提供有针对性、具体可行的改进方案。它确保代码保持极致简洁、模块化设计和零废话实现。

何时使用此技能

  • 代码审查:在合并前识别违规问题
  • 重构:寻找简化代码、提升代码质量的机会
  • 创建新模块:及早发现开发中的问题
  • 理念合规性:确保代码符合 amplihack 原则
  • 学习:了解模式为何有问题,以及如何修复
  • 指导:帮助团队成员掌握符合理念的代码模式

核心理念参考

Amplihack 开发理念侧重于:

  • 极致简洁:每种抽象都必须证明其存在价值
  • 模块化设计(积木与连接件):模块自成一体,连接点清晰
  • 零废话实现:没有存根、没有占位内容,只有可运行的代码
  • 单一职责:每个模块或函数都只有一项明确职责

检测到的代码异味

1. 过度抽象

含义:不必要的抽象层、通用基类,或没有明确价值的接口。

危害:违背“极致简洁”原则,增加的复杂度与收益不成比例,令代码更难理解和维护。

警示信号:

  • 抽象基类只有一个实现
  • 功能寥寥的通用辅助类
  • 继承层级过深(3 层及以上)
  • 只有单一实现的接口
  • 参数过多的函数

示例 - 异味:

# BAD: Over-abstracted
class DataProcessor(ABC):
    @abstractmethod
    def process(self, data):
        pass

class SimpleDataProcessor(DataProcessor):
    def process(self, data):
        return data * 2

示例 - 修正后:

# GOOD: Direct implementation
def process_data(data):
    """Process data by doubling it."""
    return data * 2

检测清单:

  • 只有 1 到 2 个具体实现的抽象类
  • 不封装状态的通用工具类
  • 类型层级超过 2 层
  • 只解决单个问题的混入类

修复策略:

  1. 明确该抽象要解决的问题
  2. 确认当前是否确实需要多个实现
  3. 删除抽象,直接实现
  4. 如果以后需要多个实现,再进行重构
  5. 原则:避免为未来过度设计

2. 复杂继承

含义:深层继承链、多重继承,或令代码流程难以看清的复杂类层级。

危害:代码难以追踪,耦合紧密,违背简洁原则,也让职责归属变得模糊。

警示信号:

  • 继承层级达到 3 层及以上(GrandparentClass -> ParentClass -> ChildClass)
  • 从非接口类进行多重继承
  • 使用继承复用代码,而不是组合
  • 多个层级的方法都被重写
  • 用于横切关注点的“混入”类

示例 - 异味:

# BAD: Complex inheritance
class Entity:
    def save(self): pass
    def load(self): pass

class TimestampedEntity(Entity):
    def add_timestamp(self): pass

class AuditableEntity(TimestampedEntity):
    def audit_log(self): pass

class User(AuditableEntity):
    def authenticate(self): pass

示例 - 修正后:

# GOOD: Composition over inheritance
class User:
    def __init__(self, storage, timestamp_service, audit_log):
        self.storage = storage
        self.timestamps = timestamp_service
        self.audit = audit_log

    def save(self):
        self.storage.save(self)
        self.timestamps.record()
        self.audit.log("saved user")

检测清单:

  • 继承深度 > 2 层
  • 从具体类进行多重继承
  • 多个继承层级的方法都被重写
  • 继承层级中没有代码复用

修复策略:

  1. 使用组合而非继承
  2. 将服务作为构造函数参数传入
  3. 让每个类处理自己的职责
  4. 这样更易于测试、理解和修改

3. 大型函数(>50 行)

它是什么:承担过多职责,难以理解、测试和修改的函数。

为什么不好:违反单一职责原则,让测试更困难,扩大漏洞范围,降低代码复用性。

警示信号:

  • 函数代码超过 50 行
  • 多层缩进(嵌套 3 层或更多 if/for)
  • 函数有 5 个或更多参数
  • 需要滚动才能看完整个函数
  • 逻辑复杂,难以命名

示例 - 有问题:

# BAD: Large function doing multiple things
def process_user_data(user_dict, validate=True, save=True, notify=True, log=True):
    if validate:
        if not user_dict.get('email'):
            raise ValueError("Email required")
        if not '@' in user_dict['email']:
            raise ValueError("Invalid email")

    user = User(
        name=user_dict['name'],
        email=user_dict['email'],
        phone=user_dict['phone']
    )

    if save:
        db.save(user)

    if notify:
        email_service.send(user.email, "Welcome!")

    if log:
        logger.info(f"User {user.name} created")

    # ... 30+ more lines of mixed concerns
    return user

示例 - 已修复:

# GOOD: Separated concerns
def validate_user_data(user_dict):
    """Validate user data structure."""
    if not user_dict.get('email'):
        raise ValueError("Email required")
    if '@' not in user_dict['email']:
        raise ValueError("Invalid email")

def create_user(user_dict):
    """Create user object from data."""
    return User(
        name=user_dict['name'],
        email=user_dict['email'],
        phone=user_dict['phone']
    )

def process_user_data(user_dict):
    """Orchestrate user creation workflow."""
    validate_user_data(user_dict)
    user = create_user(user_dict)
    db.save(user)
    email_service.send(user.email, "Welcome!")
    logger.info(f"User {user.name} created")
    return user

检测清单:

  • 函数体超过 50 行
  • 嵌套 3 层或更多
  • 包含多个无关操作
  • 难以简洁命名
  • 有 5 个或更多参数

修复策略:

  1. 为每项职责提取辅助函数
  2. 为每个函数赋予清晰、单一的职责
  3. 将小函数组合成较大的工作流
  4. 每个函数都应能在一个屏幕内完整显示
  5. 易于命名的函数通常只做一件事

4. 紧密耦合

它是什么:模块/类直接依赖具体实现,而不是抽象,导致难以测试和修改。

为什么不好:一个模块的更改会导致其他模块出问题。难以单独测试。违反模块化原则。

警示信号:

  • 在函数内部直接实例化类(db = Database())
  • 深层属性访问(obj.service.repository.data)
  • 在条件语句中硬编码类名
  • 模块从另一个模块导入所有内容
  • 模块之间存在循环依赖

示例 - 有问题:

# BAD: Tight coupling
class UserService:
    def create_user(self, name, email):
        db = Database()  # Hardcoded dependency
        user = db.save_user(name, email)

        email_service = EmailService()  # Hardcoded dependency
        email_service.send(email, "Welcome!")

        return user

    def get_user(self, user_id):
        db = Database()
        return db.find_user(user_id)

示例 - 已修复:

# GOOD: Loose coupling via dependency injection
class UserService:
    def __init__(self, db, email_service):
        self.db = db
        self.email = email_service

    def create_user(self, name, email):
        user = self.db.save_user(name, email)
        self.email.send(email, "Welcome!")
        return user

    def get_user(self, user_id):
        return self.db.find_user(user_id)

# Usage:
user_service = UserService(db=PostgresDB(), email_service=SMTPService())

检测清单:

  • 在方法内部实例化类(Service())
  • 属性链层级过深(有 3 个或更多点)
  • 硬编码类引用
  • 循环导入或依赖
  • 无法在不依赖其他模块的情况下测试模块

修复策略:

  1. 将依赖作为构造函数参数传入
  2. 使用依赖注入
  3. 轻松创建测试替身(模拟对象)
  4. 无需更改代码即可替换实现
  5. 每个模块都能独立测试

5. 缺少 __all__ 导出(Python)

它是什么:未通过 __all__ 明确定义公共接口的 Python 模块。

为什么不好:公共接口与内部实现的界限不清晰。用户会导入私有实现细节。违反“插槽”概念——连接点不明确。

警示信号:

  • __init__.py 中没有 __all__
  • 模块暴露内部函数/类
  • 用户不确定该导入什么
  • 私有名称(_function)仍可访问
  • 文档与导出内容不一致

示例 - 有问题:

# BAD: No __all__ - unclear public interface
# module/__init__.py
from .core import process_data, _internal_helper
from .utils import validate_input, LOG_LEVEL

# What should users import? All of it? Only some?

示例 - 已修复:

# GOOD: Clear public interface via __all__
# module/__init__.py
from .core import process_data
from .utils import validate_input

__all__ = ['process_data', 'validate_input']

# Users know exactly what's public and what to use

检测清单:

  • __init__.py 中缺少 __all__
  • 暴露内部函数(名称以下划线 _ 开头)
  • 不清楚什么是“公共 API”
  • 所有导入都在模块级别

修复策略:

  1. 在每个 __init__.py 中添加 __all__
  2. 仅列出公共函数/类
  3. 为内部实现添加 _ 前缀
  4. 更新文档,使其与 __all__ 一致
  5. 清晰明确,让用户知道该使用什么

分析流程

步骤 1:扫描代码结构
  1. 检查文件组织和模块边界
  2. 识别继承层次结构
  3. 扫描大型函数(统计行数)
  4. 留意是否存在 __all__
  5. 检查紧密耦合模式
步骤 2:分析每项代码异味

对于每个潜在问题:

  1. 确认其违反了设计理念
  2. 评估严重程度(严重/主要/次要)
  3. 找出具体行号
  4. 说明对系统的影响
步骤 3:生成修复方案

针对发现的每项代码异味:

  1. 清楚说明它为什么不好
  2. 展示修改前的代码
  3. 展示修改后的代码,并附上详细注释
  4. 说明违反了哪项设计理念
  5. 提供具体的重构步骤
步骤 4:生成报告
  1. 列出发现的所有代码异味
  2. 按严重程度/影响确定优先级
  3. 包含具体示例
  4. 提供可执行的修复方案
  5. 引用设计理念文档

检测规则

规则 1:抽象基类

检查:class X(ABC) 且只有 1 个具体实现

# BAD pattern detection
- Count implementations of abstract class
- If count <= 2 and not used as interface: FLAG

修复:移除抽象,直接使用具体实现

规则 2:继承深度

检查:类层次结构深度

# BAD pattern detection
- Follow inheritance chain: class -> parent -> grandparent...
- If depth > 2: FLAG

修复:改用组合

规则 3:函数行数

检查:所有函数体

# BAD pattern detection
- Count lines in function (excluding docstring)
- If > 50 lines: FLAG
- If > 3 nesting levels: FLAG

修复:提取辅助函数

规则 4:依赖实例化

检查:在方法或函数中实例化类

# BAD pattern detection
- Search for "= ServiceName()" inside methods
- If found: FLAG

修复:将其作为构造函数参数传入

规则 5:缺少 all

检查:Python 模块

# BAD pattern detection
- Look for __all__ definition
- If missing: FLAG
- If __all__ incomplete: FLAG

修复:显式定义 __all__


常见代码异味及快速修复方法

异味:“实用工具类”容器
# BAD
class StringUtils:
    @staticmethod
    def clean(s):
        return s.strip().lower()

修复:直接使用函数

# GOOD
def clean_string(s):
    return s.strip().lower()

异味:“管理器”类
# BAD
class UserManager:
    def create(self): pass
    def update(self): pass
    def delete(self): pass
    def validate(self): pass
    def email(self): pass

修复:拆分为职责明确的服务

# GOOD
class UserService:
    def __init__(self, db, email):
        self.db = db
        self.email = email

    def create(self): pass
    def update(self): pass
    def delete(self): pass

def validate_user(user): pass

异味:上帝函数
# BAD - 200 line function doing everything
def process_order(order_data, validate, save, notify, etc...):
    # 200 lines mixing validation, transformation, DB, email, logging

修复:组合小型函数

# GOOD
def process_order(order_data):
    validate_order(order_data)
    order = create_order(order_data)
    save_order(order)
    notify_customer(order)
    log_creation(order)

异味:脆弱的继承
# BAD
class Base:
    def work(self): pass
class Middle(Base):
    def work(self):
        return super().work()
class Derived(Middle):
    def work(self):
        return super().work()  # Which work()?

修复:使用清晰、可测试的组合

# GOOD
class Worker:
    def __init__(self, validator, transformer):
        self.validator = validator
        self.transformer = transformer

    def work(self, data):
        self.validator.check(data)
        return self.transformer.apply(data)

异味:隐藏依赖
# BAD
def fetch_data(user_id):
    db = Database()  # Where's this coming from?
    return db.query(f"SELECT * FROM users WHERE id={user_id}")

修复:显式注入依赖

# GOOD
def fetch_data(user_id, db):
    return db.query(f"SELECT * FROM users WHERE id={user_id}")

# Or in a class:
class UserRepository:
    def __init__(self, db):
        self.db = db

    def fetch(self, user_id):
        return self.db.query(f"SELECT * FROM users WHERE id={user_id}")

使用示例

示例 1:审查新模块
User: Review this new authentication module for code smells.

Claude:
1. Scans all Python files in module
2. Checks for each smell type
3. Finds:
   - Abstract base class with 1 implementation
   - Large 120-line authenticate() function
   - Missing __all__ in __init__.py
4. Provides specific fixes with before/after code
5. Explains philosophy violations
示例 2:识别紧密耦合
User: Find tight coupling in this user service.

Claude:
1. Traces all dependencies
2. Finds hardcoded Database() instantiation
3. Finds direct EmailService() creation
4. Shows dependency injection fix
5. Includes test example showing why it matters
示例 3:简化继承
User: This class hierarchy is too complex.

Claude:
1. Maps inheritance tree (finds 4 levels)
2. Shows each level doing what
3. Suggests composition approach
4. Provides before/after refactoring
5. Explains how it aligns with brick philosophy

分析清单

是否遵循理念
  • 没有不必要的抽象
  • 每个类/函数职责单一
  • 公共接口清晰(__all__)
  • 依赖通过注入提供,而非隐藏
  • 继承深度 <= 2 层
  • 函数 < 50 行
  • 没有死代码或存根
代码质量
  • 每个函数只负责一项明确的工作
  • 一眼就能看懂
  • 易于单独测试
  • 修改时不易破坏其他部分
  • 命名清晰地体现职责
模块化
  • 模块可以独立测试
  • 连接点(“榫头”)清晰
  • 模块之间松散耦合
  • 依赖显式声明

审查成功标准

使用此技能进行代码审查时,应当:

  • 找出所有违反理念之处
  • 提供具体行号
  • 展示修改前后的示例
  • 解释每个问题为何存在
  • 提出具体修复方法
  • 包含测试策略
  • 引用理念文档
  • 按严重程度排列优先级
  • 提供建设性意见并帮助他人学习
  • 帮助代码作者改进今后的代码

与代码质量工具集成

使用此技能的时机:

  • 代码审查期间(合并前)
  • 在拉取请求评论中
  • 创建新模块之前
  • 重构旧代码时
  • 用于团队成员培训
  • 在设计审查会议中

适用场景:

  • 代码审查流程
  • 模块规范生成
  • 重构工作流
  • 架构讨论
  • 指导与学习

资源

  • 理念:~/.amplihack/.claude/context/PHILOSOPHY.md
  • 模式:~/.amplihack/.claude/context/PATTERNS.md
  • 砖块理念:参见 PHILOSOPHY.md 中的“面向 AI 的模块化架构”
  • 零废话:参见 PHILOSOPHY.md 中的“零废话实现”

请记住

此技能有助于通过以下方式维护代码质量:

  1. 在问题演变为技术债务之前发现它们
  2. 帮助开发者理解理念
  3. 保持代码简洁且易于维护
  4. 防止系统紧密耦合
  5. 让代码更易于理解和修改

请以建设性的方式使用它——目标是学习和改进,而非批评。

评论

支持 Markdown