关于 code-smell-detector
面向使用 amplihack 的开发者的代码审查技能,可识别违背简洁与模块化原则的代码结构,并给出具体重构步骤。
主要功能
- 01识别多余抽象与复杂继承
- 02发现超长函数和紧密耦合
- 03检查 Python 模块是否缺少 __all__ 导出
- 04通过示例说明问题并提供重构步骤
适用场景
- 01合并前审查代码
- 02重构时寻找简化机会
- 03检查新模块是否符合 amplihack 原则
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ rysweet/ amplihack --skill code-smell-detector安装后在 Claude Code 中输入/code-smell-detector确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
QUICK_START.mdREADME.mdexamples/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 层
- 只解决单个问题的混入类
修复策略:
- 明确该抽象要解决的问题
- 确认当前是否确实需要多个实现
- 删除抽象,直接实现
- 如果以后需要多个实现,再进行重构
- 原则:避免为未来过度设计
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 层
- 从具体类进行多重继承
- 多个继承层级的方法都被重写
- 继承层级中没有代码复用
修复策略:
- 使用组合而非继承
- 将服务作为构造函数参数传入
- 让每个类处理自己的职责
- 这样更易于测试、理解和修改
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 个或更多参数
修复策略:
- 为每项职责提取辅助函数
- 为每个函数赋予清晰、单一的职责
- 将小函数组合成较大的工作流
- 每个函数都应能在一个屏幕内完整显示
- 易于命名的函数通常只做一件事
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 个或更多点)
- 硬编码类引用
- 循环导入或依赖
- 无法在不依赖其他模块的情况下测试模块
修复策略:
- 将依赖作为构造函数参数传入
- 使用依赖注入
- 轻松创建测试替身(模拟对象)
- 无需更改代码即可替换实现
- 每个模块都能独立测试
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”
- 所有导入都在模块级别
修复策略:
- 在每个
__init__.py中添加__all__ - 仅列出公共函数/类
- 为内部实现添加
_前缀 - 更新文档,使其与
__all__一致 - 清晰明确,让用户知道该使用什么
分析流程
步骤 1:扫描代码结构
- 检查文件组织和模块边界
- 识别继承层次结构
- 扫描大型函数(统计行数)
- 留意是否存在
__all__ - 检查紧密耦合模式
步骤 2:分析每项代码异味
对于每个潜在问题:
- 确认其违反了设计理念
- 评估严重程度(严重/主要/次要)
- 找出具体行号
- 说明对系统的影响
步骤 3:生成修复方案
针对发现的每项代码异味:
- 清楚说明它为什么不好
- 展示修改前的代码
- 展示修改后的代码,并附上详细注释
- 说明违反了哪项设计理念
- 提供具体的重构步骤
步骤 4:生成报告
- 列出发现的所有代码异味
- 按严重程度/影响确定优先级
- 包含具体示例
- 提供可执行的修复方案
- 引用设计理念文档
检测规则
规则 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 中的“零废话实现”
请记住
此技能有助于通过以下方式维护代码质量:
- 在问题演变为技术债务之前发现它们
- 帮助开发者理解理念
- 保持代码简洁且易于维护
- 防止系统紧密耦合
- 让代码更易于理解和修改
请以建设性的方式使用它——目标是学习和改进,而非批评。