mcpField
C
clean-code

clean-code

github.com/pixel-process-ug開発390 回インストール33 週間前に更新
リポジトリ

clean-code について

ソフトウェアの分析、リファクタリング、保守にクリーンコードの実践を適用するスキルです。コードの問題点を評価し、SOLID 原則、命名、エラー処理、複雑度管理を案内します。

主な機能

  1. 01コードの文脈と複雑度の分析
  2. 02コードの問題点の特定と優先順位付け
  3. 03段階的なリファクタリング
  4. 04SOLID と DRY 原則の適用
  5. 05命名とエラー処理の指針

活用シーン

  1. 01リファクタリング前のコードベース評価
  2. 02コードの問題点を減らす変更の計画
  3. 03可読性とテスト容易性の向上
  4. 04リファクタリング中の動作維持

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/pixel-process-ug/superkit-agents --skill clean-code

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

詳細

クリーンコード

概要

クリーンコードの原則を適用して、読みやすく、保守しやすく、テスト可能なソフトウェアを作成します。このスキルでは、SOLID 原則、DRY の適用、コードスメルの特定、リファクタリングパターン、命名規則、エラー処理、複雑さの管理を扱います。Robert C. Martin、Martin Fowler、Kent Beck の著作に基づいています。

開始時に宣言: 「コード品質を向上させるため、クリーンコードスキルを使用します。」


フェーズ 1:現在のコードを分析する

目標: 変更を加える前に、コードを全体の文脈で読み、理解します。

アクション
  1. コードを全体の文脈で読む(断片だけでなく)
  2. コードの責務と目的を特定する
  3. 循環的複雑度を測定する
  4. 結合関係と依存関係を把握する
  5. 既存のテストを確認する
停止 — 次の条件を満たすまでフェーズ 2 に進まないでください:
  • コードを全体の文脈で読んだ
  • 目的と責務を理解した
  • 複雑度の高い箇所を特定した
  • 既存のテストカバレッジを把握した

フェーズ 2:コードスメルを特定する

目標: 以下の参照表を使用して、すべてのコードスメルを記録します。

肥大化
スメル検出方法リファクタリング
長いメソッド30 行超メソッドの抽出
大きなクラス300 行超、または責務が 5 つ超クラスの抽出
長いパラメーターリストパラメーターが 3 つ超パラメーターオブジェクトの導入
データの塊同じパラメーターが一緒に現れるクラスの抽出
プリミティブ型への執着小さなオブジェクトの代わりにプリミティブ型を使用値オブジェクトへの置き換え
オブジェクト指向の濫用
スメル検出方法リファクタリング
switch 文型による switchポリモーフィズムへの置き換え
並行継承各サブクラスに対応するサブクラスが必要階層の統合
継承の拒否サブクラスが継承したメソッドを無視する継承を委譲に置き換え
変更の妨げ
スメル検出方法リファクタリング
発散的変更複数の理由で 1 つのクラスが変更されるクラスの抽出(SRP)
ショットガン手術1 つの変更が多くのクラスに及ぶメソッドの移動、クラスのインライン化
不要物
スメル検出方法リファクタリング
デッドコード到達不能、または未使用削除
投機的一般化「念のため」の未使用の抽象化階層の縮小、削除
不適切なコードを説明するコメント不明瞭なコードを補うコメント名前の変更、メソッドの抽出
停止 — 次の条件を満たすまでフェーズ 3 に進まないでください:
  • すべてのコードスメルを記録した
  • 各スメルに優先度(高/中/低)を付けた
  • それぞれのリファクタリング方針を特定した

フェーズ 3:リファクタリングを適用する

目標: リファクタリングパターンを 1 つずつ適用し、その都度テストで確認します。

アクション
  1. 一度に適用するリファクタリングは 1 つだけにする
  2. 変更のたびにテストを実行する
  3. テストが失敗した場合は、直ちに変更を元に戻す
  4. コードがクリーンになるまで続ける
  5. 命名、構造、ドキュメントを見直す
停止 — 次の条件を満たしたらリファクタリング完了です:
  • 優先度の高いスメルをすべて解消した
  • 変更のたびにすべてのテストが成功した
  • リファクタリング中に動作を変更していない
  • 新しいチームメンバーにも読みやすいコードになっている

SOLID 原則

S — 単一責任の原則

クラス/モジュールが変更される理由は、ただ 1 つであるべきです。

スメル: 無関係な複数の理由で変更されるクラス。 修正: 責務を別々のクラスに抽出します。

O — オープン・クローズドの原則

拡張に対して開き、変更に対して閉じます。

スメル: 新しい型が増えるたびに大きくなる switch 文。 修正: ポリモーフィズム、ストラテジーパターン、またはプラグインアーキテクチャを使用します。

L — リスコフの置換原則

サブタイプは、基底型と置き換え可能でなければなりません。

スメル: サブクラスが「未サポート」をスローするようにメソッドをオーバーライドする。 修正: 階層を再構成し、継承よりコンポジションを優先します。

I — インターフェース分離の原則

クライアントは、使用しないメソッドに依存すべきではありません。

問題点: メソッドが多いインターフェースがあり、実装側が一部を何もしない処理にしています。 修正方法: インターフェースを、より小さく目的を絞ったものに分割します。

D — 依存性逆転の原則

具象ではなく、抽象に依存します。

問題点: 上位モジュールが下位モジュールを直接インポートしています。 修正方法: インターフェースや抽象クラスを介して依存関係を注入します。


命名規則

ルール
要素規則例
変数格納するものを表す名詞n ではなく userCount
ブール値is/has/can/should を接頭辞に付けるisActive、hasPermission
関数動作を表す動詞calculateTotal、fetchUsers
定数UPPER_SNAKE_CASEMAX_RETRY_COUNT
クラスPascalCase の名詞UserRepository、PaymentService
インターフェース能力を表すSerializable、Cacheable
名前の長さのガイドライン
スコープ長さ例
ループカウンター1~2文字i、j(短いループのみ)
ラムダーパラメーター文脈が明確な場合は1~3文字users.filter(u => u.active)
ローカル変数短く、かつ説明的total、result
関数名中程度の長さで説明的calculateMonthlyRevenue
クラス名必要なだけ長くAuthenticationTokenValidator

関数のガイドライン

サイズと構造
  • 関数は1つのことだけを行うべきです
  • 理想:5~15行(定型コードを除く)
  • 最大:30行(超える場合は切り出します)
  • パラメーターの最大数:3(超える場合はオプションオブジェクトを使います)
ガード節(早期リターン)
// Bad: nested conditions
function getDiscount(user) {
  if (user) {
    if (user.isPremium) {
      if (user.orderCount > 10) {
        return 0.2;
      }
    }
  }
  return 0;
}

// Good: guard clauses
function getDiscount(user) {
  if (!user) return 0;
  if (!user.isPremium) return 0;
  if (user.orderCount <= 10) return 0;
  return 0.2;
}

エラー処理のパターン

選択表
方法使用する場面例
Result 型関数型スタイル、想定される失敗Result<T, E> の戻り値型
個別の例外OOP スタイル、例外的なケースthrow new ValidationError(...)
エラーコードC スタイルの API、言語をまたぐ場合戻りコード + メッセージ
Option/Maybe値が存在する場合としない場合があるOption<User>
Result 型パターン
type Result<T, E = Error> =
  | { success: true; data: T }
  | { success: false; error: E };

function parseConfig(raw: string): Result<Config, ParseError> {
  try {
    const config = JSON.parse(raw);
    if (!isValidConfig(config)) {
      return { success: false, error: new ParseError('Invalid config structure') };
    }
    return { success: true, data: config };
  } catch {
    return { success: false, error: new ParseError('Invalid JSON') };
  }
}
エラー処理で避けること
  • エラーを捕捉して、何もせずに握りつぶしてはいけません
  • 制御フローに例外を使ってはいけません
  • エラーを示すために null を返してはいけません
  • 文脈を追加せずにログを記録して再スローしてはいけません

複雑度の指標

範囲リスクレベル対応
1-5低対応不要
6-10中程度リファクタリングを検討します
11-20高リファクタリングするべきです
21+危険リファクタリングが必須です
複雑度を下げる方法
  1. 複雑な条件式を、名前を付けたブール値に切り出します
  2. ネストした条件分岐をガード節に置き換えます
  3. 型チェックの代わりにポリモーフィズムを使います
  4. より小さな関数に分解します
  5. switch/if の連鎖の代わりにルックアップテーブルを使います

DRY 適用の選択表

状況DRY を適用するか理由
ロジックが完全に重複しているはい同じロジックは1か所にまとめるべきです
3回以上出現するはいRule of Three によりパターンが確認できます
2回だけ出現する待ちますたまたま似ているだけかもしれません
構造は似ているが目的が異なるいいえ変更する理由が異なります
抽象化によって複雑さが増すいいえDRY より明瞭さを優先します

コメントの考え方

良いコメント
種類例
理由(判断の根拠)// リストが事前にソートされており、項目数が10Kを超えるため二分探索を使う
法的な情報著作権、ライセンスのヘッダー
チケット番号付き TODO// TODO(PROJ-123): レート制限を追加する
警告// WARNING: これはスレッドセーフではありません
公開 API のドキュメント公開インターフェース用の JSDoc/TSDoc
悪いコメント(削除して、代わりにコードを修正します)
種類例
コードの言い換えcounter++ の前にある // カウンターをインクリメントする
コメントアウトされたコード代わりにバージョン管理を使います
作業記録のコメント代わりに git log を使います
閉じ波括弧のコメント} // if の終わり

アンチパターン/よくある間違い

アンチパターン問題である理由適切な方法
早すぎる抽象化意図が異なるコードをDRY化するRule of Threeを待つ
ゴッドクラスあらゆることを把握し、あらゆることを実行する責務ごとに分割する(SRP)
フィーチャーエンヴィーメソッドが自クラスのデータよりも他クラスのデータを多く使用するメソッドをデータの所有者に移す
文字列型データ列挙型や型を使うべき箇所に文字列を使う適切な型を定義する
マジックナンバー意味が不明確で、エラーが起きやすい名前付き定数を使う
ブール値の罠ブール値の引数によって動作が変わる関数名前付きオプションまたは別々の関数を使う
過剰設計存在しない問題のために抽象化するYAGNI — 必要になるまで作らない

統合ポイント

スキル関係
code-reviewレビューで特定されたコードスメルを、clean-codeで解消する
test-driven-developmentTDDにより、リファクタリング中の動作を維持する
senior-frontendフロントエンドコンポーネントはクリーンコードの原則に従う
senior-backendバックエンドサービスはSOLIDとクリーンアーキテクチャに従う
performance-optimizationクリーンコードにより、パフォーマンス最適化が容易になる
systematic-debuggingクリーンコードはデバッグしやすい

不変性に関する方針

  • デフォルトでconstを使う(JavaScript/TypeScript)
  • readonlyプロパティとReadonlyArrayを使う
  • 変更よりスプレッド構文/分割代入を優先する
  • 状態には不変な更新パターンを使う
  • パフォーマンスプロファイリングで必要性が示された場合にのみ変更する

スキルの種類

FLEXIBLE — コンテキストに応じて原則を適用します。すべての関数を5行にする必要はなく、すべてのパターンがSOLIDに従う必要もありません。理論的な純粋さより、チームにとっての読みやすさを優先し、適切に判断してください。

コメント