mcpField
C
codeprobe-code-smells

codeprobe-code-smells

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

codeprobe-code-smells について

コードの臭いとアンチパターンを調べる codeprobe スキルです。保守性、オブジェクト指向設計、結合度、可読性を対象とし、検出しきい値を設定できます。

主な機能

  1. 01長いメソッドと巨大クラスの検出
  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-code-smells

インストール後、Claude Code で/codeprobe-code-smellsを入力して読み込まれたか確認します。

詳細

スタンドアロンモード

オーケストレーター経由ではなく直接呼び出された場合は、まず次の手順を実行する必要があります。

  1. 出力仕様、実行モード、制約について、../codeprobe/shared-preamble.md を読み込みます(相対パスはこの SKILL.md の場所、つまりユーザーのプロジェクトではなく、同階層にある codeprobe スキルディレクトリを基準に解決します)。
  2. プロジェクトの技術スタックに基づいて、該当する参照ファイルを ../codeprobe/references/ から読み込みます(同じパス解決方法を使用します)。
  3. ユーザーが別の指定をしない限り、デフォルトで full モードを使用します。

コードスメルとアンチパターンの検出

対象範囲

このサブスキルでは、次のカテゴリに分類されるコードスメルとアンチパターンを検出します。

  1. 肥大化 — 長すぎるメソッド、大きすぎるクラス、データの塊、プリミティブ型への執着
  2. オブジェクト指向の濫用 — 機能への偏り、不適切な親密さ、拒否された継承
  3. 変更の妨げ — ショットガン手術、変更の分散
  4. 不要な要素 — デッドコード、投機的な汎用化、中間者
  5. 結合 — 時間的結合
  6. 可読性 — マジックナンバー、ブール値の曖昧さ、深いネスト

検出対象外

  • 生成コード — マイグレーション、コンパイル済み出力、ベンダーディレクトリ(vendor/、node_modules/、dist/、build/、.next/)、自動生成ファイル(GraphQL codegen、Prisma client など)。
  • 長いセットアップメソッドを含むテストファイル — テストのコンテキストは異なるため、テストデータを準備する長い setUp() メソッドや beforeEach() メソッドは想定内であり、問題ありません。
  • エントリ数の多い設定ファイル — キーと値の組み合わせが50個ある設定ファイルは、「大きすぎるクラス」のスメルではありません。
  • データマイグレーションファイル — これらは本質的に手続き型であり、長いメソッドを含むことがよくあります。
  • リポジトリにチェックインされたサードパーティーコード(ベンダーライブラリなど)。
  • codeprobe-solid または codeprobe-architecture ですでに検出された構造上の問題 — 大きなクラスは、SRP違反や神クラスとしても検出される場合があります。このサブスキルでも引き続き検出して報告する必要がありますが、オーケストレーターが同じ場所で重複する指摘を統合します。

検出手順

設定可能なしきい値

分析の前に、プロジェクトのルートに .codeprobe-config.json ファイルがあるか確認します。存在する場合は、severity_overrides セクションを読み込み、次のデフォルト値を調整します。

しきい値設定キーデフォルト
長すぎるメソッドのLOC上限long_method_loc30
大きすぎるクラスのLOC上限large_class_loc300
深いネストの最大レベル数deep_nesting_max3
肥大化
IDプレフィックススメルシグナル検出方法デフォルトのしきい値重大度
SMELL長すぎるメソッド関数/メソッドがLOCのしきい値を超えている各関数/メソッド本体の行数を数えます(空行と1行のコメントは除外)。long_method_loc のしきい値と比較します。しきい値の2倍を超えるメソッドは、重大度を「Major」に引き上げます。> 30 LOCMinor
SMELL大きすぎるクラスクラスがLOCのしきい値を超えている各クラス定義の合計行数を数えます。large_class_loc のしきい値と比較します。しきい値の2倍を超えるクラスは、まだ「Major」でない場合、重大度を「Major」に引き上げます。「Critical」には引き上げません。大きなクラスは保守性の問題であり、本番環境の欠陥ではないためです。> 300 LOCMajor
SMELLデータの塊同じ3個以上のパラメーターが3箇所以上で一緒に渡されている関数/メソッドのシグネチャを検索します。3個以上のパラメーターのグループが、異なる3つ以上の関数シグネチャまたは呼び出し箇所に一緒に出現しているかを特定します。これらはパラメーターオブジェクトまたは値オブジェクトに抽出する必要があります。3個以上のパラメーター、3箇所以上Minor
SMELLプリミティブ型への執着値オブジェクトが適切な場面で文字列/整数が使われているドメイン概念を表す文字列/整数の変数を探します。メールアドレス(正規表現によるインライン検証)、金額(数値と通貨が別々に渡される)、電話番号、複数箇所で比較されるステータス文字列、郵便番号、複数レイヤーにわたってプレーンな文字列として渡されるUUIDなどが該当します。パターン認識Minor
オブジェクト指向の濫用
ID PrefixSmellSignalHow to DetectDefault ThresholdSeverity
SMELLフィーチャーエンヴィメソッドが、自身のデータよりも他のオブジェクトのデータに3回以上アクセスしているメソッドが $other->property または other.property を参照する回数と、$this->property または this.property(あるいは self.)を参照する回数を数えます。外部参照が内部参照の3倍以上であれば、そのメソッドは他のクラスに属する可能性があります。外部アクセス3回以上軽微
SMELL不適切な親密さクラスが他のクラスの private/protected な内部実装にアクセスしているリフレクションを使ったアクセス(setAccessible(true)、protected フィールドにアクセスする __get、__set マジックメソッド)、friend class パターン、または慣例的に private とされるプロパティ(Python/JS で _ を接頭辞に付けたもの)への直接アクセスを検索します。1件以上重大
SMELL継承の拒絶サブクラスが継承しているにもかかわらず、親クラスのメソッドの大半を使用していないサブクラスを調べます。親クラスに N 個の public メソッドがあり、サブクラスがその30%未満しかオーバーライドせず、さらに大半のメソッドで super/parent:: を呼び出していない場合、そのサブクラスには継承関係が本当に必要ではない可能性があります。親クラスのメソッドの過半数が未使用軽微
変更を妨げるもの
ID PrefixSmellSignalHow to DetectDefault ThresholdSeverity
SMELLショットガン手術1つの概念を変更するために5ファイル以上の編集が必要多数のファイルに現れる単一の概念(フィールド名、ステータス値、ビジネスルールなど)を検索します。同じ定数、カラム名、ビジネス用語が、単一の信頼できる情報源に集約されずに5ファイル以上に現れる場合は、問題として指摘します。1つの概念につき5ファイル以上重大
SMELL発散的変更1つのクラスが、無関係な理由で3回以上変更されている大規模なクラス(200 LOC超)を調べます。メソッドが、互いに無関係な個別の関心事に分かれているか確認します。1つのクラスがユーザー認証、メールの書式設定、レポート生成をすべて担っている場合、発散的変更が生じています。これら3つの領域のいずれかが変更されるたびに、このクラスも変更する必要があります。個別の関心事が3つ以上重大
不要なもの
ID PrefixSmellSignalHow to DetectDefault ThresholdSeverity
SMELLデッドコード到達不能な分岐、未使用のインポート、コメントアウトされたコードブロック次を検索します。(1)ファイル内のどこからも参照されていないシンボルの import/use/require 文、(2)コメントアウトされたコードブロック(ドキュメントではなくコード構文を含む、3行以上連続したコメント行)、(3)コードベースのどこからも呼び出されていない関数/メソッド(プロジェクト全体を Grep で検索)、(4)if (false) または if (0) ブロック、条件なしの return/throw/exit の後にある到達不能なコード。1件以上軽微
SMELL投機的一般化唯一の実装しかなく、2つ目の実装も見込まれない抽象化/インターフェースインターフェース、抽象クラス、またはジェネリック型パラメーターのうち、具体的な実装がちょうど1つしかないものを検索します。その抽象化が DI コンテナー設定やテストモックに現れず、ドメインにも将来のバリエーションを示す要素がない場合、時期尚早な抽象化として指摘します。実装が1つのみ提案
SMELLミドルマンロジックを追加せず、他のクラスに処理を委譲するだけのクラスすべてのメソッドが、注入された依存先の同じメソッドを呼び出して結果を返すだけで、ロジック、検証、変換、エラー処理を追加していないクラスを探します。このクラスは不要な間接層を追加しています。すべてのメソッドが単純な委譲のみ軽微
結合
ID プレフィックスにおいシグナル検出方法デフォルトのしきい値重大度
SMELL時間的結合特定の順序でメソッドを呼び出す必要がありますが、それを強制する仕組みがありません次のようなパターンを探します。(1)メソッド B より前にメソッド A を呼び出す必要があるのに、コンパイル時または実行時のチェックがない。(2)init()/setup() を process() より前に呼び出す必要があるのに、クラスでは先に process() を呼び出せてしまう。(3)共有の可変状態を扱うメソッドを順番に呼び出す必要があり、順序を入れ替えるとバグが発生する。"must call X first" や "call after Y" のようなコメントも確認します。暗黙的な順序依存重大
可読性
ID プレフィックスにおいシグナル検出方法デフォルトのしきい値重大度
SMELLマジックナンバービジネスロジックに名前付き定数を使わず、数値や文字列リテラルをハードコードしている条件分岐、計算、ビジネスロジックで使われている数値リテラル(0、1、-1 を除く)と文字列リテラルを検索します。名前付き定数を使わず、ロジックの経路に現れる 86400、3.14159、"pending"、0.15 などの値を検出します。除外対象:配列インデックス、0/1 のループ境界、数学ライブラリで使われる一般的な数学定数。ロジックの経路にあるすべての値軽微
SMELLブール値の判別困難ブール値のパラメーターを 2 個以上持つメソッドbool/boolean パラメーターを 2 個以上持つ関数/メソッドのシグネチャを検索します。process(true, false, true) のような呼び出しは可読性に欠けます。名前付きパラメーター、列挙型、またはオプションオブジェクトの使用を提案します。ブール値のパラメーターが 2 個以上軽微
SMELL深いネストインデントレベルがしきい値を超えている各関数のネストの深さを数えます。別の構文の中にネストされた if、for、while、foreach、switch、try、match は、それぞれ 1 レベルとして加算します。ネストが deep_nesting_max のしきい値を超えた場合に検出します。早期リターン、ガード節、またはメソッドの抽出を提案します。3 レベル超軽微

ID プレフィックスと修正プロンプトの例

すべての検出結果には SMELL- プレフィックスを付け、SMELL-001、SMELL-002 のように連番を振ります。

修正プロンプトの例
  • "UserService@register の 45~90 行目をプライベートメソッド validateAndNormalizeInput() に抽出してください。このメソッドは 120 LOC あり、入力の検証(45~65 行目)、データの正規化(66~80 行目)、永続化(81~90 行目)という無関係な 3 つの処理を行っています。永続化は register() に残し、ほかの 2 つの処理を抽出してください。"
  • "app/Services/CacheService.php の 55 行目にあるマジックナンバー 86400 を、クラスの先頭に定義した名前付き定数 SECONDS_PER_DAY = 86400 に置き換えてください。"
  • "OrderProcessor.php の 30 行目にある processOrder(bool $isExpress, bool $requiresSignature, bool $isFragile) をリファクタリングし、3 つのブール値パラメーターの代わりに ShippingOptions 値オブジェクトを受け取るようにしてください。名前付きプロパティを持つ ShippingOptions クラスを作成してください。"
  • "PaymentGateway.php の 88~105 行目にあるコメントアウトされたコードブロックを削除してください。これは以前の実装の不要なコードです。後で必要になった場合は、バージョン管理から復元できます。"
  • "ReportGenerator.php の 20 行目にある generate() メソッドは 95 LOC あります。データ取得のロジック(25~50 行目)を fetchReportData() に、書式設定のロジック(51~85 行目)を formatReport() に抽出してください。generate() メソッドは、この 2 つの手順を調整する役割を担うようにしてください。"

コメント