Communityコーディング&開発github.com

msewell/agent-stuff

他の皆と同じように、私のエージェント関連の知見を共有します。

agent-stuff とは?

このスキルは、ソフトウェア設計における「継承よりコンポジション」の原則を実践的に適用するためのガイドを提供します。主な目的は、開発者やAIエージェントが、データのバリアント、振る舞いの戦略、クロスカッティングな関心事といった様々な変化軸に対して、適切な設計メカニズム(コンポジション、代数的データ型(ADT)、継承)を選択できるようにすることです。Claude CodeやCursorなどのAIエージェントプラットフォームで利用できるように設計されており、段階的なリファクタリング計画、コードレビューのチェックリスト、CI/CDパイプラインで適用可能なメトリクスも含まれています。デフォルトでコンポジションを推奨し、明確な正当性がない限り継承の導入を避けるという規範に基づいて、具体的な判断基準と実装手順を提供します。

対応~Claude Code~Codex CLI~Cursor
npx skills add msewell/agent-stuff

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

継承よりコンポジションの適用

クイックスタート

  1. 変化軸を特定する: データのバリアント、アルゴリズム、クロスカッティングな振る舞い、またはフレームワークの制約。
  2. デフォルトはコンポジション: 継承が、代替可能性と安定性によって明確に正当化される場合を除き、デフォルトでコンポジションを選択する。
  3. バリアント集合が閉じており、データを伴う場合: オープンな継承よりも、代数的データ型(ADT)/ sealed型(sealed type)を優先する。
  4. 具体的な移行計画を作成する: テスト、ロールアウト順序、レビューのチェックポイントを含めること。

リファレンスルーティング(段階的開示)

現在のタスクに必要なファイルのみを参照してください:

デフォルトのワークフロー

  1. 現在のモデルを評価する

    • 基底クラス、サブクラス数、階層の深さ、既知の問題点をリストアップする。
    • 各変化軸を、データバリアント、振る舞い戦略、インフラストラクチャ関心事のいずれかに分類する。
  2. メカニズムを選択する(デフォルト優先)

    • 振る舞いのバリエーション、実行時の差し替え、または複数軸の変更には コンポジション を選択する。
    • 閉じており、データを運ぶバリアントで、網羅的な処理が必要な場合は、ADT/sealed型 を選択する。
    • 以下の条件がすべて満たされる場合にのみ 継承 を選択する: 真のis-a関係、Liskovの置換原則に準拠した代替可能性、安定した階層。
  3. ターゲットとなる構造を設計する

    • 最小限のコラボレーターコントラクト(協定)を定義し、変動性、複数の実装、独立したテストが必要な箇所にインターフェース/プロトコルを導入する。
    • 必須のコラボレーターにはコンストラクタインジェクションを使用する。
    • 継承の深さは浅く保つ(やむを得ないフレームワーク基底クラスを除き、目標は2以下)。
  4. 段階的に移行計画を立てる

    • 最初に特性テスト(characterization tests)を追加する。
    • 内部を置き換える前に、シーム(seam: インターフェース/ファサード)を導入する。
    • 一度に一つのサブクラスのパスを移行する。
    • パリティチェック(等価性検証)が通った後にのみ、不要になった階層の部品を削除する。
  5. 検証とガードレールを設定する

    • チェックリストに基づくレビューを実行する。
    • DIT(継承の深さ)、オーバーライド比率、デコレータの深さに関するCIメトリクス/チェックを追加する。
    • フレームワークで要求される継承については、明示的な免除(waiver)を記録する。

不変のデフォルト

  • デフォルトではコンポジションを優先する。
  • コードの再利用だけを目的として継承を導入しない。
  • コラボレーターのインターフェースは狭く保つ。
  • サービスロケータパターンは避け、依存関係は明示的でなければならない。
  • 深いデコレータスタック(>3)や広い継承ツリーは設計上のアンチパターン(コードの不吉な匂い)として扱う。

出力契約

ガイダンスを求められた場合、以下のセクションを順に返すこと:

  1. 判断: コンポジション、ADT、または継承。
  2. 理由: 結合度、変更軸、実行時の要件、テスト容易性への影響。
  3. 設計スケッチ: ターゲットとなるインターフェース/型とコンポジションルート。
  4. 移行手順: 検証ポイントを含む、小さく可逆的なステップ。
  5. レビュー/CIチェック: チェックリスト項目と測定可能なしきい値。

エッジケース

  • フレームワークで継承が強制される場合: 継承は境界(フレームワークとの接点)に留め、内部はコンポジションで構成する。
  • 言語に委譲(delegation)の糖衣構文がない場合: 転送(forwarding)用の小さなヘルパージェネレーター/テンプレートを使用する。
  • パフォーマンスが重要なパス: 間接層(インダイレクション)を追加する前に、ディスパッチのオーバーヘッドを測定する。
  • 小さく安定したドメイン: 網羅性が必要な場合、sealedな継承は許容されることがある。

例

入力: 「BaseReport に12のサブクラスがあり、新しいフォーマットを追加するたびにサブクラスが増えます。どうすればよいですか?」

出力(概要):

  • 判断: 階層をコンポジション(Strategy + オプションでDecorator)に置き換える。
  • 理由: 複数軸のバリエーションとオーバーライドの多いサブクラスは、分類学のドリフト(taxonomy drift)を示している。
  • 設計スケッチ: ReportRenderer、HeaderPolicy、FooterPolicy、OutputFormatter インターフェースを一つの ReportService でコンポーズする。
  • 移行: 特性テスト → Strategyの抽出 → サブクラスごとの移行 → サブクラスの削除。
  • ガードレール: DIT警告 >3、オーバーライド比率警告 >0.5、デコレータの深さ警告 >3。

関連スキル