mcpField
C
codeprobe-solid

codeprobe-solid

github.com/machineroom-dev其他5107 次安装6 天前更新
代码仓库

关于 codeprobe-solid

面向开发者的代码审查技能,用于检查代码是否符合五项 SOLID 设计原则。它识别职责划分、扩展性、可替换性、接口设计和依赖方面的潜在问题。

主要功能

  1. 01审查五项 SOLID 原则
  2. 02标记职责混杂的类
  3. 03检查扩展与替换模式
  4. 04发现过宽或未使用的接口
  5. 05检测对具体依赖的耦合

适用场景

  1. 01在代码变更中审查架构
  2. 02定位承担无关职责的类
  3. 03评估基于类型分支的扩展性
  4. 04查找直接依赖基础设施的代码

安装

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

$npx skills add https://github.com/machineroom-dev/codeprobe --skill codeprobe-solid

安装后在 Claude Code 中输入/codeprobe-solid确认已加载。

详细介绍

独立模式

如果直接调用(而非通过编排器调用),必须先:

  1. 阅读 ../codeprobe/shared-preamble.md(相对于此 SKILL.md 的位置解析,即同级的 codeprobe 技能目录,而非用户的项目),了解输出约定、执行模式和限制。
  2. 根据项目的技术栈,从 ../codeprobe/references/(以相同方式解析)加载适用的参考文件。
  3. 默认使用 full 模式,除非用户另有指定。

SOLID 原则审计器

领域范围

此子技能用于检测对五项 SOLID 原则的违反:

  1. 单一职责原则(SRP) — 一个类或模块应只有一个变更理由。
  2. 开闭原则(OCP) — 软件实体应对扩展开放,对修改关闭。
  3. 里氏替换原则(LSP) — 子类型必须能够替换其基类型,且不影响程序正确性。
  4. 接口隔离原则(ISP) — 不应强迫客户端依赖其不使用的接口。
  5. 依赖倒置原则(DIP) — 高层模块不应依赖低层模块;两者都应依赖抽象。

不会标记的情况

  • 包含多个字段的简单 DTO/值对象 — 如果类表示单一数据概念,那么属性较多不违反 SRP。
  • 无需依赖注入的小型脚本和 CLI — 设计应与实际需求相称。
  • 用于 switch 语句且稳定、封闭的枚举(例如方位和星期几)— 只有当变体可能增加时,OCP 才适用。
  • 遵循框架约定的框架生成类(例如 Laravel 迁移、Django 管理类、带有标准回调的 Rails ActiveRecord 模型)。
  • 汇总设置工具的测试辅助类 — 测试基础设施有不同的设计限制。

检测说明

SRP — 单一职责原则
ID 前缀信号检测方法严重程度
SRP类有 5 个或更多执行不同任务的公共方法统计公共方法。如果有 5 个或更多,检查这些方法是否围绕单一职责展开,还是涉及多个关注点(例如,身份验证 + 电子邮件 + 数据库)。留意暗示不同领域的方法名前缀。主要
SRP方法超过 30 行代码且处理多个关注点统计每个方法的行数(不包括空行和注释)。如果超过 30 行代码,检查该方法是否处理了多个不同步骤(验证、转换、持久化、通知),这些步骤是否可以提取出来。次要
SRP类名含义模糊标记名为 Manager、Handler、Utils、Helper、Processor、Service(未限定领域)的类 — 这些名称表明该类没有明确的单一用途。例外:如果类较小(少于 5 个方法且少于 100 行代码),则降级为建议。次要
SRP构造函数有 5 个或更多依赖项统计构造函数参数或注入的依赖项。5 个或更多依赖项表明该类可能承担过多职责。检查这些依赖项是否服务于不同领域。主要
OCP — 开闭原则
ID 前缀信号检测方法严重程度
OCP基于类型或状态的 switch/if-else 链查找基于类型、状态、角色或种类字段进行分支的 switch/if-else 链 — 尤其是添加新变体需要修改此代码块的情况。统计分支数量:对于可能扩展的类型,3 个或更多分支即为信号。主要
OCP变体可能增加但没有扩展点找到基于类型的 switch/if-else 语句后,检查是否存在接口、抽象类、策略模式或插件机制,以便在不修改现有代码的情况下添加新变体。如果没有,则标记。次要
LSP — 里氏替换原则
ID 前缀信号检测方法严重程度
LSP子类重写方法,但改变了其语义检查重写的方法:子类是否返回了根本不同的类型、改变了返回值的含义,或产生了父类不会产生的副作用?比较方法签名和文档注释。重大
LSP子类抛出父类未声明的异常查找重写的方法,检查其抛出的异常是否未出现在父类的 throws 子句或文档化的契约中。在动态语言中,查找父类方法不会抛出异常,但重写方法中出现 raise/throw 的情况。重大
LSP子类忽略父类行为,或不执行任何操作查找方法体为空、使用 pass、return null、return 或包含 // not implemented 注释的重写方法。这说明子类拒绝履行父类的契约。次要
LSP多态调用后进行 instanceof/类型检查搜索对本应以多态方式使用的对象进行 instanceof、is_a、typeof、type()、is 检查的代码。如果代码先对基类类型调用方法,随后又检查具体类型,则说明可替换性遭到破坏。重大
ISP — 接口隔离原则
ID 前缀信号检测方法严重程度
ISP接口有 8 个或更多方法统计每个接口/抽象类/协议中声明的方法数量。如果有 8 个或更多方法,该接口可能过于宽泛。检查这些方法是否可归为不同的组。次要
ISP类实现接口,但将方法留空或抛出异常查找接口实现,检查是否有一个或多个方法为空、返回 null、抛出 NotImplementedError/UnsupportedOperationException,或只包含 pass/TODO 注释。重大
ISP一个接口中包含多个互不相关的方法组分析接口的方法:它们是否属于 2 个或更多不同的职责组(例如,读取操作 + 写入操作 + 通知方法)?如果是,则应拆分该接口。重大
DIP — 依赖倒置原则
ID 前缀信号检测方法严重程度
DIP业务逻辑中出现 new ConcreteClass()搜索业务逻辑方法中直接实例化(new ClassName()、直接调用构造函数)的基础设施类或服务类。排除:DTO、值对象、异常、集合、工厂和 DI 容器注册。重大
DIP高层模块直接导入基础设施层内容检查导入语句:领域/业务逻辑模块是否直接导入数据库驱动、HTTP 客户端、文件系统库或第三方 SDK,而没有抽象层?查找 import mysql、use Illuminate\Support\Facades\DB、from requests import 等模式。重大
DIP没有构造函数注入,而是静态调用具体依赖的方法查找业务逻辑中类似 Database::query()、Cache::get()、Logger.log() 的静态方法调用,且没有注入接口的情况。该类通过静态访问与具体实现紧密耦合。次要

ID 前缀与修复提示词示例

  • SRP- — 单一职责原则违规
  • OCP- — 开闭原则违规
  • LSP- — 里氏替换原则违规
  • ISP- — 接口隔离原则违规
  • DIP- — 依赖倒置原则违规

在每个前缀内按顺序为发现项编号:SRP-001、SRP-002、OCP-001 等。

修复提示词示例
  • “重构 src/OrderService.php:将支付逻辑(第 45-78 行)提取到新的 PaymentService 类中。通过构造函数将 PaymentService 注入 OrderService。将 calculateTotal()、applyDiscount() 和 processPayment() 方法移至新类。”
  • “将 NotificationSender 中对 $type 的 switch 语句(第 30-65 行)替换为策略模式:创建一个 NotificationChannel 接口,包含 send(Message $message) 方法。创建 EmailChannel、SmsChannel 和 PushChannel 实现。使用 NotificationChannelFactory 按类型解析正确的通道。”
  • “在 UserRepository.php 中,将第 23 行的 new MySqlConnection() 替换为构造函数注入:在构造函数中添加一个 DatabaseConnectionInterface $connection 参数,并使用它替代具体类的实例化。”

评论

支持 Markdown