oop-best-practices について
日常のコーディングやレビューで、可読性、オブジェクトの責務、保守性を高めるためのオブジェクト指向設計スキルです。レビュー手順に加え、実践的な指針と言語別の資料を提供します。
主な機能
- 01命名と抽象化の指針
- 02カプセル化と責務の確認
- 03メッセージベースのオブジェクト連携
- 04継承よりコンポジションを優先
- 05コードレビューの手順
- 06多言語の例と参考資料
活用シーン
- 01クラスの責務とインターフェースの確認
- 02曖昧な命名や抽象化の改善
- 03ドメインオブジェクトへの振る舞いの配置
- 04リファクタリング時の連携の簡素化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ luckys/ agent-skills --skill oop-best-practicesインストール後、Claude Code で/oop-best-practicesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/advanced-modeling-concepts.mdbook-influences.mdchange-driven-design.mdcore-principles.mdcsharp-examples.mddependency-management.mddomain-language-and-modeling.mdfran-iglesias-practical-guidance.mdgo-examples.mdgradual-abstraction.mdinterface-depth.mdjava-examples.mdlanguage-examples.mdmessage-based-design.mdmethod-design.mdnaming-and-abstractions.mdobject-calisthenics.mdoop-good-practices-examples.mdphp-examples.mdpython-examples.mdruby-examples.mdrust-examples.mdsimple-design-rules.mdsolid-principles.mdthird-party-notices.mdtypescript-examples.mdvalue-objects-advanced.md詳細
OOP のベストプラクティス
可読性、凝集度、長期的な保守性に影響する、日常的なコーディングの判断にこのスキルを使います。
特に、次のような点が重要なタスクで役立ちます。
- より適切な命名と、意図を明確にする抽象化
- オブジェクトの責務とカプセル化された不変条件の明確化
- メッセージベースの協調と、役割を中心としたオブジェクト
- 日常的な設計判断における、継承よりコンポジションの優先
作業スタイル
- コンパイラーのためだけでなく、次に読む人のためにコードを書きます。
- 振る舞いは、それを担う概念の近くに置きます。
- 巧妙なオブジェクトグラフより、シンプルな協調を優先します。
- 名前、境界、API を使って意図を明らかにします。
- オブジェクト自身がルールを担える場合は、そうします。
レビューワークフロー
-
概念を特定します。
- このコードはどのような概念をモデル化していますか?
- その概念に属するルールや不変条件は何ですか?
-
境界を確認します。
- オブジェクトは生のデータを公開していますか、それとも意味のある振る舞いを提供していますか?
- 呼び出し側は内部構造を知りすぎる必要がありますか?
-
構造を確認します。
- メソッドは複数の抽象化レベルを混在させていますか?
- クラスには変更理由が複数ありますか?
- 意図をすぐに理解できるだけの明確な名前が付いていますか?
-
必要十分な範囲で改善します。
- 明確になるように名前を変更する
- メソッドを抽出する
- 値オブジェクトを抽出する
- ファーストクラスコレクションを抽出する
- データを所有するオブジェクトに振る舞いを移す
- 責務に応じてクラスを分割する
追加のレビューポイント
命名と抽象化の規律
- 名前が適切でない場合は、表現を磨く前に抽象化を見直します。
- 概念を失わせたり、将来の再利用を過度に推測したりする早すぎる抽象化は避けます。
- 構文の重複だけでなく、知識の重複を取り除きます。
カプセル化とオブジェクトの責務
- ルールは、それを所有する概念に移します。
- 意味のある振る舞いを持つ概念では、単なるデータ保持オブジェクトより、振る舞いを備えたオブジェクトを優先します。
- オブジェクトがルールを担える場合は、サービスが調整役を担うようにします。
メッセージベースの設計
- 協調相手からデータを取り出すより、意味のある振る舞いを依頼することを優先します。
- 具体的な内部構造ではなく、役割とメッセージに依存します。
- 公開インターフェースは小さく、明示的で、意図が伝わるものにします。
構造のシンプルさ
- 振る舞いが個別に変わる場合は、コンポジションを優先します。
- 継承は浅く、実態に即したものにします。
- 連鎖的な参照をたどらなければならないオブジェクトグラフは避けます。
日々のルール
- 短い名前より、意図が伝わる名前を優先します。
- メソッドは浅く保ち、抽象化の一つのレベルに集中させます。
- 分岐の煩雑さを減らせる場合は、早期リターンを使います。
- クラスは単に小さくするのではなく、凝集性を保ちます。
- 同一性が重要でなく、意味上の保証、型安全性、または振る舞いによってドメイン型を導入する価値がある場合は、値オブジェクトを導入します。
- 協調相手からデータを取得して別の場所で判断するより、何をすべきか伝えることを優先します。
- コレクション自体が不変条件を持つ場合は、ファーストクラスコレクションを導入します。
- 値オブジェクトには、意味上の等価性、それに対応するハッシュ動作、そして深い不変性を備えた観察可能性を持たせます。オブジェクト参照の等価性や、浅い
readonlyに頼らないでください。 - 変化しやすい具体的な実装詳細ではなく、小さな役割に依存します。
- 振る舞いが個別に変わる場合は、コンポジションを優先します。
- 公開 API は、内部実装の詳細より小さく保ちます。
良い兆候
- クラス名が、そのクラスの担う振る舞いと一致している。
- 無効な状態が早い段階で拒否される。
- ほとんどのメソッドは、無関係なヘルパーを読まなくても理解できる。
- 呼び出し側が依存する範囲が小さい。
- コードベース全体で同じ概念に一貫した名前が付いている。
警告サイン
- メソッドを読みやすくするために、複数のコメントが必要になる。
- クラスが主にゲッターとセッターを公開している。
- 多くの呼び出し側で、同じ検証や分岐のロジックが繰り返されている。
- ある概念を変更すると、無関係な多数のファイルまで編集が必要になる。
- オブジェクトモデルが、振る舞いを別の場所で後付けしたデータ運搬のように見える。
参考資料
-
インターフェースの複雑さ、中継レイヤー、または呼び出し元が追跡する必要のある状態を評価する場合は、
references/interface-depth.mdを参照してください。 -
コーディングのヒューリスティクスを簡潔にまとめた内容については、
references/core-principles.mdを参照してください。 -
このスキルの基盤となる主要な書籍を、出典を中心にまとめたガイドについては、
references/book-influences.mdを参照してください。 -
命名や抽象化の質が主な課題である場合は、
references/naming-and-abstractions.mdを参照してください。 -
オブジェクト間の協調や役割が最も重要な場合は、
references/message-based-design.mdを参照してください。 -
日常的な OO 設計の範囲にとどまる、より豊かなオブジェクトの選択肢については、
references/advanced-modeling-concepts.mdを参照してください。 -
Fran Iglesias から導き出された、実践的な OO のヒューリスティクスについては、
references/fran-iglesias-practical-guidance.mdを参照してください。 -
単一責任、オープン・クローズド、依存関係逆転に関する SOLID 違反や設計上の課題が主な場合は、
references/solid-principles.mdを参照してください。 -
クラスやメソッドを整理する際に、厳格な OO の規律に関するルールを適用する場合は、
references/object-calisthenics.mdを参照してください。 -
結合度、依存関係の方向、協力オブジェクトの注入に関する判断が焦点である場合は、
references/dependency-management.mdを参照してください。 -
メソッドの長さ、抽象化のレベル、意図を明らかにする構造が課題である場合は、
references/method-design.mdを参照してください。 -
抽象化を導入する適切なタイミングが不明確な場合や、設計を早い段階で過度に複雑化している場合は、
references/gradual-abstraction.mdを参照してください。 -
言語別のサンプルファイル(TypeScript、Java、Python、C#、Ruby、PHP、Go、Rust)の一覧については、
references/language-examples.mdを参照してください。 -
Go における OOP の概念(構造体、暗黙的なインターフェース、コンポジション、継承なし)については、
references/go-examples.mdを参照してください。 -
Rust における OOP の概念(構造体、トレイト、newtype パターン、不変性としての所有権)については、
references/rust-examples.mdを参照してください。 -
Kent Beck のシンプルな設計の 4 つのルール(テストに合格する、意図を明らかにする、重複がない、要素を最小限にする)と、CodelyTV の例については、
references/simple-design-rules.mdを参照してください。 -
Demeter、Tell Don't Ask、名前付きコンストラクション、コレクションのアイデンティティ、依存関係の役割、およびコース内の反例について、複数言語にわたる修正済みの解説を参照するには、
references/oop-good-practices-examples.mdを参照してください。 -
値オブジェクトの包括的なガイドとして、選定基準、不変条件の所有、構築と解析、等価性とハッシュ化、深い不変性、振る舞い、オプショナル性、第一級コレクション、永続化、テスト、安全な進化を扱う
references/value-objects-advanced.mdを参照してください。
関連スキル
- オブジェクトの所有権が、一貫性、ライフサイクル、リポジトリ、またはトランザクションの境界も定義する場合は、
ddd-best-practicesを使用してください。 - 値オブジェクトの契約テスト、境界分析、プロパティベーステスト、決定論的なフィクスチャには、
tdd-best-practicesを使用してください。 - リスクの高いコードやレガシーコードを変更する場合は、
refactoring-best-practicesを使用してください。 - 主な検討事項がパターンの選択である場合は、
design-patterns-best-practicesを使用してください。 - これらのオブジェクトを公開する HTTP API の設計には、
rest-api-best-practicesを使用してください。
影響を受けた出典
このスキルは、以下で重視されている考え方をまとめたものです。
- Carlos Blé 著『Sustainable Code』
- Kent Beck 著『Implementation Patterns』
- Sandi Metz 著『Practical Object-Oriented Design in Ruby』
- Sandi Metz 著『99 Bottles of OOP』
- Fran Iglesias の
design-principles記事 - Fran Iglesias の
good-practices記事 - Fran Iglesias の
Object Calisthenicsシリーズ - CodelyTV OOP Good Practices コース(段階的な例や、教育目的で上書きされた反例を含む)
- CodelyTV Aggregates コース
- CodelyTV Value Objects コース
- CodelyTV シンプルな設計の 4 つのルールのコース(意図を示す命名、YAGNI、インターフェース、重複、テストに関する意図的な反例を含む)