codeprobe-solid

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
    完整模式。

SOLID Principles Auditor

SOLID原则审计器

Domain Scope

适用领域

This sub-skill detects violations of the five SOLID principles:
  1. Single Responsibility Principle (SRP) — A class or module should have only one reason to change.
  2. Open/Closed Principle (OCP) — Software entities should be open for extension but closed for modification.
  3. Liskov Substitution Principle (LSP) — Subtypes must be substitutable for their base types without altering program correctness.
  4. Interface Segregation Principle (ISP) — Clients should not be forced to depend on interfaces they do not use.
  5. Dependency Inversion Principle (DIP) — High-level modules should not depend on low-level modules; both should depend on abstractions.

此子技能用于检测是否违反以下五项SOLID原则:
  1. 单一职责原则(SRP) —— 一个类或模块应该只有一个引起变化的原因。
  2. 开闭原则(OCP) —— 软件实体应对扩展开放,对修改关闭。
  3. 里氏替换原则(LSP) —— 子类必须能够替换其基类,且不影响程序正确性。
  4. 接口隔离原则(ISP) —— 客户端不应被迫依赖自己不需要的接口。
  5. 依赖倒置原则(DIP) —— 高层模块不应依赖低层模块,两者都应依赖抽象。

What It Does NOT Flag

不会标记的情况

  • Simple DTOs/value objects with multiple fields — having many properties is not an SRP violation when the class represents a single data concept.
  • Small scripts and CLIs that don't need dependency injection — proportional design matters.
  • Enums used in switches where the enum is stable and closed (e.g., compass directions, days of the week) — OCP applies when variants are likely to grow.
  • Framework-generated classes following framework conventions (e.g., Laravel migrations, Django admin classes, Rails ActiveRecord models with standard callbacks).
  • Test helper classes that aggregate setup utilities — test infrastructure has different design constraints.

  • 包含多字段的简单DTO/值对象 —— 当类代表单一数据概念时,拥有多个属性不属于SRP违规。
  • 无需依赖注入的小型脚本与CLI工具 —— 设计需与规模相匹配。
  • 用于switch语句的稳定枚举(如方位、星期几)—— 仅当变体可能增加时,OCP才适用。
  • 遵循框架约定的框架生成类(如Laravel迁移、Django后台类、带有标准回调的Rails ActiveRecord模型)。
  • 聚合设置工具的测试辅助类 —— 测试基础设施有不同的设计约束。

Detection Instructions

检测说明

SRP — Single Responsibility Principle

SRP — 单一职责原则

ID PrefixSignalHow to DetectSeverity
SRP
Class has 5+ public methods doing unrelated thingsCount public methods. If 5+ exist, check whether they cluster around a single responsibility or span multiple concerns (e.g., authentication + email + database). Look for method name prefixes that suggest different domains.Major
SRP
Method exceeds 30 LOC doing multiple concernsCount lines in each method (excluding blank lines and comments). If > 30 LOC, check whether the method handles multiple distinct steps (validation, transformation, persistence, notification) that could be extracted.Minor
SRP
Class name is vagueFlag classes named
Manager
,
Handler
,
Utils
,
Helper
,
Processor
,
Service
(when not domain-qualified) — these names suggest the class has no clear single purpose. Exception: if the class is small (< 5 methods, < 100 LOC), downgrade to suggestion.
Minor
SRP
Constructor takes 5+ dependenciesCount constructor parameters or injected dependencies. 5+ dependencies suggest the class has too many responsibilities. Check whether dependencies serve different domains.Major
ID前缀信号检测方法严重程度
SRP
类包含5个及以上执行无关操作的公共方法统计公共方法数量。如果有5个及以上,检查这些方法是否围绕单一职责聚合,还是跨越多个关注点(如身份验证+邮件+数据库)。查看方法名称前缀是否暗示不同领域。严重
SRP
方法代码行数超过30行且处理多个关注点统计每个方法的代码行数(排除空行和注释)。如果超过30行,检查该方法是否处理多个可拆分的独立步骤(验证、转换、持久化、通知)。轻微
SRP
类名称模糊标记名为
Manager
Handler
Utils
Helper
Processor
Service
(未限定领域)的类——这些名称表明类没有明确的单一职责。例外:如果类规模较小(少于5个方法、少于100行代码),降级为建议。
轻微
SRP
构造函数接收5个及以上依赖统计构造函数参数或注入的依赖数量。5个及以上依赖表明类职责过多。检查这些依赖是否服务于不同领域。严重

OCP — Open/Closed Principle

OCP — 开闭原则

ID PrefixSignalHow to DetectSeverity
OCP
Switch/if-else chains on type or statusLook for
switch
/
if-else
chains that branch on a type, status, role, or kind field — especially where adding a new variant requires modifying this block. Count the number of cases: 3+ cases on a growable type is a signal.
Major
OCP
No extension point where variants are likely to growWhen a switch/if-else on type is found, check whether there is an interface, abstract class, strategy pattern, or plugin mechanism that would allow adding new variants without modifying the existing code. If absent, flag it.Minor
ID前缀信号检测方法严重程度
OCP
基于类型或状态的switch/if-else链式判断查找基于类型、状态、角色或类别字段的
switch
/
if-else
链式判断——尤其是添加新变体需要修改该代码块的情况。统计分支数量:针对可扩展类型的3个及以上分支即为信号。
严重
OCP
变体可能增加但无扩展点当发现基于类型的switch/if-else判断时,检查是否存在接口、抽象类、策略模式或插件机制,允许在不修改现有代码的情况下添加新变体。如果不存在,则标记为违规。轻微

LSP — Liskov Substitution Principle

LSP — 里氏替换原则

ID PrefixSignalHow to DetectSeverity
LSP
Subclass overrides method but changes semanticsCheck overridden methods: does the subclass return a fundamentally different type, change the meaning of the return value, or produce side effects the parent does not? Compare method signatures and doc comments.Major
LSP
Subclass throws exception parent doesn't declareLook for overridden methods that throw exceptions not present in the parent's throws clause or documented contract. In dynamic languages, look for
raise
/
throw
in overrides where the parent method doesn't throw.
Major
LSP
Subclass ignores or no-ops parent behaviorLook for overridden methods with empty bodies,
pass
,
return null
,
return
, or
// not implemented
comments. The subclass is refusing the parent's contract.
Minor
LSP
instanceof
/type checks after polymorphic call
Search for
instanceof
,
is_a
,
typeof
,
type()
,
is
checks on objects that should be used polymorphically. If code calls a method on a base type and then checks the concrete type, it signals broken substitutability.
Major
ID前缀信号检测方法严重程度
LSP
子类重写方法但改变语义检查重写的方法:子类是否返回完全不同的类型、改变返回值的含义,或产生父类没有的副作用?对比方法签名和文档注释。严重
LSP
子类抛出父类未声明的异常查找重写方法中抛出的、未在父类throws声明或文档契约中提及的异常。在动态语言中,查找父类方法不抛出但子类重写方法中使用
raise
/
throw
的情况。
严重
LSP
子类忽略或空实现父类行为查找重写方法中包含空方法体、
pass
return null
return
// not implemented
注释的情况。子类违反了父类的契约。
轻微
LSP
多态调用后进行instanceof/类型检查查找对应多态使用的对象进行
instanceof
is_a
typeof
type()
is
类型检查的代码。如果代码调用基类型方法后又检查具体类型,表明可替换性被破坏。
严重

ISP — Interface Segregation Principle

ISP — 接口隔离原则

ID PrefixSignalHow to DetectSeverity
ISP
Interface has 8+ methodsCount methods declared in each interface/abstract class/protocol. If 8+, the interface is likely too broad. Check whether the methods cluster into distinct groups.Minor
ISP
Class implements interface but leaves methods empty or throwingLook for interface implementations where one or more methods are empty, return null, throw
NotImplementedError
/
UnsupportedOperationException
, or contain only
pass
/
TODO
comments.
Major
ISP
Multiple unrelated method groups in one interfaceAnalyze the interface's methods: do they fall into 2+ distinct responsibility groups (e.g., read operations + write operations + notification methods)? If so, the interface should be split.Major
ID前缀信号检测方法严重程度
ISP
接口包含8个及以上方法统计每个接口/抽象类/协议中声明的方法数量。如果超过8个,该接口可能过于宽泛。检查方法是否可划分为不同的组。轻微
ISP
类实现接口但部分方法为空或抛出异常查找接口实现中存在一个或多个空方法、返回null、抛出
NotImplementedError
/
UnsupportedOperationException
,或仅包含
pass
/
TODO
注释的情况。
严重
ISP
单个接口包含多个无关方法组分析接口的方法:是否可分为2个及以上独立的职责组(如读取操作+写入操作+通知方法)?如果是,该接口应拆分。严重

DIP — Dependency Inversion Principle

DIP — 依赖倒置原则

ID PrefixSignalHow to DetectSeverity
DIP
new ConcreteClass()
inside business logic
Search for direct instantiation (
new ClassName()
, direct constructor calls) of infrastructure or service classes inside business logic methods. Exclude: DTOs, value objects, exceptions, collections, factories, and DI container registrations.
Major
DIP
High-level module imports from infrastructure layer directlyCheck import statements: does a domain/business logic module import directly from database drivers, HTTP clients, file system libraries, or third-party SDKs without an abstraction layer? Look for patterns like
import mysql
,
use Illuminate\Support\Facades\DB
,
from requests import
.
Major
DIP
No constructor injection — static method calls to concrete dependenciesLook for static method calls like
Database::query()
,
Cache::get()
,
Logger.log()
in business logic where no interface is injected. The class is tightly coupled to the concrete implementation via static access.
Minor

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 Prefixes & Fix Prompt Examples

ID前缀与修复提示示例

  • SRP-
    — Single Responsibility Principle violations
  • OCP-
    — Open/Closed Principle violations
  • LSP-
    — Liskov Substitution Principle violations
  • ISP-
    — Interface Segregation Principle violations
  • DIP-
    — Dependency Inversion Principle violations
Number findings sequentially within each prefix:
SRP-001
,
SRP-002
,
OCP-001
, etc.
  • SRP-
    —— 单一职责原则违规
  • OCP-
    —— 开闭原则违规
  • LSP-
    —— 里氏替换原则违规
  • ISP-
    —— 接口隔离原则违规
  • DIP-
    —— 依赖倒置原则违规
每个前缀下的发现按顺序编号:
SRP-001
SRP-002
OCP-001
等。

Fix Prompt Examples

修复提示示例

  • "Refactor
    src/OrderService.php
    : extract payment logic (lines 45-78) into a new
    PaymentService
    class. Inject
    PaymentService
    via constructor into
    OrderService
    . Move methods
    calculateTotal()
    ,
    applyDiscount()
    , and
    processPayment()
    to the new class."
  • "Replace the switch on
    $type
    in
    NotificationSender
    (lines 30-65) with a Strategy pattern: create a
    NotificationChannel
    interface with a
    send(Message $message)
    method. Create
    EmailChannel
    ,
    SmsChannel
    , and
    PushChannel
    implementations. Use a
    NotificationChannelFactory
    to resolve the correct channel by type."
  • "In
    UserRepository.php
    , replace
    new MySqlConnection()
    at line 23 with constructor injection: add a
    DatabaseConnectionInterface $connection
    parameter to the constructor and use it instead of the concrete instantiation."
  • "重构
    src/OrderService.php
    :将支付逻辑(第45-78行)提取到新的
    PaymentService
    类中。通过构造函数将
    PaymentService
    注入
    OrderService
    。将
    calculateTotal()
    applyDiscount()
    processPayment()
    方法移至新类。"
  • "将
    NotificationSender
    中基于
    $type
    的switch语句(第30-65行)替换为策略模式:创建带有
    send(Message $message)
    方法的
    NotificationChannel
    接口。实现
    EmailChannel
    SmsChannel
    PushChannel
    类。使用
    NotificationChannelFactory
    根据类型解析对应的渠道。"
  • "在
    UserRepository.php
    中,将第23行的
    new MySqlConnection()
    替换为构造函数注入:为构造函数添加
    DatabaseConnectionInterface $connection
    参数,并使用该参数替代具体实例化。"