mcpField
S
single-responsibility-principle

single-responsibility-principle

github.com/yanko-belov開発1348 回インストール40 週間前に更新
リポジトリ

single-responsibility-principle について

single-responsibility-principleは、各クラス、モジュール、関数の責任を一つに保つためのコーディングスキルです。機能を分割するタイミングを見極め、無関係な責任の追加を避ける方法を示します。

主な機能

  1. 01単一責任の原則の適用
  2. 02複数の変更理由の検出
  3. 03肥大化したクラスの兆候の特定
  4. 04責任が明確なコンポーネントの抽出

活用シーン

  1. 01新しいクラスやモジュールの設計
  2. 02無関係なメソッドを持つクラスのレビュー
  3. 03既存の巨大クラスのリファクタリング

インストール

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

$npx skills add https://github.com/yanko-belov/code-craft --skill single-responsibility-principle

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

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

user-system/
AnalyticsService.ts
AuthenticationService.ts
index.ts
NotificationService.ts
ProfileService.ts

詳細

単一責任の原則(SRP)

概要

クラスが変更される理由は、1つだけであるべきです。

すべてのモジュール、クラス、関数は、機能の単一の部分に責任を持つべきです。クラスの役割を説明するのに「そして」が必要なら、責任を持ちすぎています。

使用する場面

  • 新しいクラス、モジュール、サービスを作成するとき
  • 既存のクラスにメソッドを追加するとき
  • 「複数のことを行う」コードをレビューするとき
  • 「ここに追加するだけでいい」と感じたとき

絶対のルール

NEVER add functionality that introduces a second reason to change.

例外はありません:

  • 「このほうが速いから」は理由になりません
  • 「メソッドをもう1つ追加するだけだから」は理由になりません
  • 「リファクタリングには時間がかかりすぎるから」は理由になりません
  • 「テックリードにそう言われたから」は理由になりません
  • 「すでに本番環境で稼働しているから」は理由になりません

プレッシャーの下で SRP に違反することも、やはり SRP 違反です。

検出方法:「そして」テスト

クラスを1文で説明してください。「そして」が含まれていたら、分割しましょう。

説明判定
「ユーザー認証を処理する」✅ 単一の責任
「認証を処理し、そしてメールを送信する」❌ 2つの責任
「注文を管理し、そして決済を処理し、そして在庫を追跡する」❌ 3つの責任

検出方法:変更する理由

このクラスを変更する必要が生じる理由を列挙してください:

// ❌ BAD: UserManager - 4 reasons to change
class UserManager {
  login() {}           // Auth logic changes
  updateProfile() {}   // Profile requirements change  
  sendEmail() {}       // Email provider changes
  trackAnalytics() {}  // Analytics requirements change
}

// ✅ GOOD: Split by responsibility
class AuthService { login() {} }
class ProfileService { updateProfile() {} }
class NotificationService { sendEmail() {} }
class AnalyticsService { track() {} }

プレッシャーに抗うための手順

SRP に違反するようプレッシャーを受けた場合は、次の手順に従ってください:

1. 時間的プレッシャー

「とにかくすぐに動くようにして」

対応: 神クラスを作るのにかかる時間は、責務を絞ったクラスを作る時間と変わりません。「手っ取り早い」解決策は技術的負債を生み、後々その10倍のコストがかかります。

行動: クラスを分けて作成しましょう。時間は余計にかかりません。

2. サンクコストによるプレッシャー

「そのクラスはもうあるんだから、そこに追加するだけでいい」

対応: 肥大化したクラスに追加すれば、さらに悪化します。すでに間違っているからといって、もっと間違った状態にしてよい理由にはなりません。

行動: 責務を絞った新しいクラスを作成しましょう。時間が許せば、既存のクラスをリファクタリングしてください。

3. 権限によるプレッシャー

「テックリードから、全部1つのクラスに入れるよう言われた」

対応: 根拠を示して、敬意を持って異議を唱えましょう。却下された場合は、懸念を記録して従います。ただし、神クラスを黙って作ることは決してしないでください。

行動:

"I'd recommend splitting this because [specific reason]. 
If we keep it together, we'll likely need to refactor when [consequence].
Should I proceed with the split, or document this as tech debt?"
4. スコープクリープ

「そこを作業するついでに、Xも追加して」

対応: 新しい機能は、新しいクラス(または、適切な既存のクラス)に追加します。

行動: 「X は独自のサービスにするべきです。XService を作成します。」

危険信号 — 作業を止めて再検討してください

以下のいずれかに気づいたら、SRP に違反しようとしています:

  • クラスの中核的な目的と関係のないメソッドを追加している
  • クラスのファイルが200行を超えている
  • クラスにパブリックメソッドが5~7個を超えてある
  • クラス内を移動するためにセクションコメントが必要
  • 無関係な機能を編集するために、複数の開発者がこのクラスを変更する
  • クラス名に具体的なドメインを示す語がなく、「Manager」「Handler」「Processor」「Service」が含まれている

どれも、クラスを分割すべきという意味です。

既存の違反をリファクタリングする

既存の神クラスに遭遇した場合:

  1. 悪化させない — 責任をこれ以上追加しない
  2. 触るついでに切り出す — 変更時に、作業対象の部分を切り出す
  3. 負債を記録する — 今すぐリファクタリングできない場合は、チケットを作成する
// Found: OrderService with 500 lines handling orders, payments, inventory, emails

// ❌ WRONG: Add shipping logic to OrderService
// ✅ RIGHT: Create ShippingService, note that OrderService needs refactoring

よくある正当化(どれも不適切)

言い訳実態
「1つのクラスに入れたほうが速い」速くはありません。どちらの方法でも入力するコードは同じです。
「小さなクラスは過剰設計だ」小さなクラスこそ、適切な設計です。
「メソッドをもう1つ追加するだけだ」そうして、いつも神クラスが生まれます。
「あとでリファクタリングできる」しないでしょう。技術的負債は積み重なります。
「クラスはすでに大きい」続ける理由ではなく、止める理由です。
「関連する機能だ」関連していることと、同じ責任であることは別です。
「セクションコメントがあれば移動しやすい」移動しやすくする必要があるなら、クラスが大きすぎます。

クイックリファレンス

症状対応
クラスが X と Y の両方を行うXService と YService に分割する
無関係なメソッドを追加する新しいクラスを作成する
ファイルが 200 行を超える切り出せる箇所を探す
変更する理由が複数ある理由ごとにクラスを 1 つ作る
「Manager/Handler/Processor」という名前より具体的な名前にするか、分割する

要点

クラスは 1 つ。責務は 1 つ。変更する理由は 1 つ。

これに反するよう迫られたら、異議を唱えるか、記録に残すか、いずれにせよ適切な構造を作成してください。

時間的なプレッシャー、既存のコード、権限者からの要求にかかわらず、ゴッドクラスは決して正解ではありません。

コメント