mcpField
C
codeprobe-solid

codeprobe-solid

github.com/machineroom-devその他5107 回インストール6 日前に更新
リポジトリ

codeprobe-solid について

5つのSOLID設計原則に照らしてコードを監査するコードレビュー用スキルです。責務、拡張性、置換可能性、インターフェース、依存関係の問題を特定します。

主な機能

  1. 015つの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 原則監査

対象範囲

このサブスキルでは、5 つの SOLID 原則への違反を検出します。

  1. 単一責任の原則(SRP) — クラスまたはモジュールが変更される理由は 1 つだけであるべきです。
  2. 開放/閉鎖の原則(OCP) — ソフトウェアの構成要素は拡張に対して開かれ、変更に対して閉じられているべきです。
  3. リスコフの置換原則(LSP) — サブタイプはプログラムの正しさを損なうことなく、基底型と置き換え可能でなければなりません。
  4. インターフェース分離の原則(ISP) — クライアントが使用しないインターフェースへの依存を強制されるべきではありません。
  5. 依存関係逆転の原則(DIP) — 上位モジュールは下位モジュールに依存すべきではありません。両者とも抽象に依存すべきです。

検出対象外

  • 複数のフィールドを持つ単純な DTO/値オブジェクト — クラスが単一のデータ概念を表す場合、プロパティが多くても SRP 違反にはなりません。
  • 依存性注入を必要としない小規模なスクリプトや CLI — 設計は規模に見合ったものであることが重要です。
  • 列挙型が安定しており、選択肢が固定されている場合の switch 内での使用(例:方角、曜日)— OCP が適用されるのは、選択肢が増える可能性がある場合です。
  • フレームワークの規約に従う、フレームワークが生成したクラス(例:Laravel のマイグレーション、Django の管理クラス、標準的なコールバックを使用する Rails ActiveRecord モデル)。
  • セットアップ用ユーティリティをまとめたテストヘルパークラス — テスト基盤には異なる設計上の制約があります。

検出手順

SRP — 単一責任の原則
ID PrefixSignalHow to DetectSeverity
SRP無関係な処理を行う public メソッドが 5 個以上あるクラスpublic メソッドの数を数えます。5 個以上ある場合、単一の責任にまとまっているか、複数の関心事(例:認証+メール+データベース)にまたがっているかを確認します。異なるドメインを示唆するメソッド名の接頭辞にも注目します。Major
SRP複数の関心事を扱う、30 LOC を超えるメソッド各メソッドの行数を数えます(空行とコメントは除外)。30 LOC を超える場合、抽出可能な複数の異なる処理(検証、変換、永続化、通知など)を扱っているか確認します。Minor
SRPクラス名が曖昧Manager、Handler、Utils、Helper、Processor、Service(ドメイン名で修飾されていない場合)という名前のクラスを検出します。これらの名前は、クラスに明確な単一の目的がないことを示唆します。例外:クラスが小さい(メソッドが 5 個未満かつ 100 LOC 未満)場合は、指摘の重大度を下げて提案とします。Minor
SRPコンストラクターが 5 個以上の依存関係を受け取るコンストラクターパラメーターまたは注入された依存関係の数を数えます。依存関係が 5 個以上ある場合、クラスの責任が多すぎる可能性があります。依存関係が異なるドメインに属するか確認します。Major
OCP — 開放/閉鎖の原則
ID PrefixSignalHow to DetectSeverity
OCP型またはステータスに基づく switch/if-else の連鎖型、ステータス、ロール、種別のフィールドに基づいて分岐する switch/if-else の連鎖を探します。特に、新しい選択肢を追加する際にこのブロックの変更が必要となるものに注目します。ケース数を数えます。拡張可能な型に対するケースが 3 個以上ある場合は、検出の兆候です。Major
OCP選択肢が増える可能性があるのに拡張ポイントがない型に基づく switch/if-else が見つかった場合、既存コードを変更せずに新しい選択肢を追加できるインターフェース、抽象クラス、ストラテジーパターン、プラグイン機構があるか確認します。ない場合は指摘します。Minor
LSP — リスコフの置換原則
ID Prefixシグナル検出方法重大度
LSPサブクラスがメソッドをオーバーライドし、意味を変更しているオーバーライドされたメソッドを確認します。サブクラスが根本的に異なる型を返す、戻り値の意味を変える、または親クラスにはない副作用を発生させていないかを調べます。メソッドのシグネチャとドキュメントコメントを比較します。Major
LSPサブクラスが親クラスで宣言されていない例外をスローする親クラスの throws 節やドキュメント化された契約に記載されていない例外をスローする、オーバーライドされたメソッドを探します。動的言語では、親メソッドが例外をスローしない場合に、オーバーライド内で raise/throw が使われていないかを確認します。Major
LSPサブクラスが親クラスの動作を無視する、または何もしない空の本体、pass、return null、return、または // not implemented コメントを含む、オーバーライドされたメソッドを探します。サブクラスが親クラスの契約を拒否しています。Minor
LSPポリモーフィックな呼び出し後の instanceof/型チェックポリモーフィックに使用すべきオブジェクトに対する instanceof、is_a、typeof、type()、is のチェックを検索します。コードが基底型のメソッドを呼び出した後に具象型を確認している場合、置換可能性が損なわれていることを示しています。Major
ISP — インターフェース分離の原則
ID Prefixシグナル検出方法重大度
ISPインターフェースにメソッドが8個以上ある各インターフェース/抽象クラス/プロトコルで宣言されているメソッド数を数えます。8個以上ある場合、インターフェースの範囲が広すぎる可能性があります。メソッドが異なるグループに分かれているか確認します。Minor
ISPクラスがインターフェースを実装しているが、メソッドが空、または例外をスローする1つ以上のメソッドが空、null を返す、NotImplementedError/UnsupportedOperationException をスローする、または pass/TODO コメントだけを含む、インターフェースの実装を探します。Major
ISP1つのインターフェースに複数の無関係なメソッドグループがあるインターフェースのメソッドを分析します。読み取り操作、書き込み操作、通知メソッドなど、2つ以上の異なる責務グループに分かれていませんか。その場合、インターフェースを分割する必要があります。Major
DIP — 依存関係逆転の原則
ID Prefixシグナル検出方法重大度
DIPビジネスロジック内の new ConcreteClass()ビジネスロジックのメソッド内で、インフラストラクチャクラスやサービスクラスを直接インスタンス化(new ClassName()、直接のコンストラクター呼び出し)していないか検索します。DTO、値オブジェクト、例外、コレクション、ファクトリー、DI コンテナーへの登録は除外します。Major
DIP高レベルモジュールがインフラストラクチャ層から直接インポートしているimport 文を確認します。ドメイン/ビジネスロジックのモジュールが、抽象化レイヤーを介さずにデータベースドライバー、HTTP クライアント、ファイルシステムライブラリ、またはサードパーティ製 SDK から直接インポートしていませんか。import mysql、use Illuminate\Support\Facades\DB、from requests import のようなパターンを探します。Major
DIPコンストラクターインジェクションがなく、具象依存への静的メソッド呼び出しがあるインターフェースが注入されていないビジネスロジック内で、Database::query()、Cache::get()、Logger.log() のような静的メソッド呼び出しを探します。クラスが静的アクセスを通じて具象実装に強く結合しています。Minor

ID Prefix と修正プロンプトの例

  • SRP- — 単一責任の原則への違反
  • OCP- — オープン・クローズドの原則への違反
  • LSP- — リスコフの置換原則への違反
  • ISP- — インターフェース分離の原則への違反
  • DIP- — 依存関係逆転の原則への違反

各 Prefix 内で、指摘事項に連番を付けます:SRP-001、SRP-002、OCP-001 など。

プロンプトの例を修正する
  • 「src/OrderService.php をリファクタリングし、45〜78 行目の決済ロジックを新しい PaymentService クラスに切り出してください。コンストラクターを通じて PaymentService を OrderService に注入してください。calculateTotal()、applyDiscount()、processPayment() メソッドを新しいクラスに移してください。」
  • 「NotificationSender の 30〜65 行目にある $type による switch 文を、Strategy パターンに置き換えてください。send(Message $message) メソッドを持つ NotificationChannel インターフェースを作成してください。EmailChannel、SmsChannel、PushChannel の実装を作成してください。NotificationChannelFactory を使って、タイプに応じた適切なチャネルを解決してください。」
  • 「UserRepository.php の 23 行目にある new MySqlConnection() をコンストラクターインジェクションに置き換えてください。コンストラクターに DatabaseConnectionInterface $connection パラメーターを追加し、具象クラスをインスタンス化する代わりにそれを使用してください。」

コメント