Communitygithub.com

Castle-Solutions/landing

ディープモジュール設計のための共有語彙。モジュールのインターフェース設計や改善、深堀り機会の発見、シームの配置決定、テスト容易性やAI操作性の向上、または他のスキルがディープモジュールの語彙を必要とする場合に使用します。

landing とは?

このスキルは、ソフトウェア設計において「ディープモジュール」を設計・評価するための統一された語彙と原則を提供します。ディープモジュールとは、小さなインターフェースの背後に多くの振る舞いを隠したモジュールであり、呼び出し側にレバレッジ(学習単位あたりの能力)をもたらし、保守者に局所性(変更やバグの集中)をもたらし、全員にテスト容易性をもたらします。具体的な用語(Module, Interface, Implementation, Depth, Seam, Adapter, Leverage, Locality)を厳密に定義し、「コンポーネント」「サービス」「API」「境界」といった曖昧な言葉を避けることで、チーム内のコミュニケーションを正確にします。また、テスト容易性のための設計原則(依存関係の注入、副作用の回避、小さな表面積)や、シームの導入判断基準(1つのアダプタは仮説、2つで現実)も含まれています。このスキルはClaude Code, Codex, CursorなどのAIエージェントがコード設計やリファクタリングの文脈で利用することを想定しており、他のスキル(DEEPENING.md, DESIGN-IT-TWICE.md)と連携してさらに深い分析を行えます。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Castle-Solutions/landing/tree/HEAD/.agents/skills/codebase-design

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

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

ドキュメント

コードベース設計

ディープモジュールを設計する:小さなインターフェースの背後に多くの振る舞いを持ち、クリーンなシームに配置され、そのインターフェースを通じてテスト可能なモジュール。コードを設計または再構成するあらゆる場面で、この言語と原則を使用してください。目的は、呼び出し側にとってのレバレッジ、保守者にとっての局所性、そして全員にとってのテスト容易性です。

用語集

以下の用語を正確に使用してください。「コンポーネント」「サービス」「API」「境界」などの言葉で代用しないでください。一貫した言語がすべての要点です。

Module(モジュール):インターフェースと実装を持つあらゆるもの。意図的にスケールにとらわれません:関数、クラス、パッケージ、または階層をまたがるスライス。避けること:ユニット、コンポーネント、サービス。

Interface(インターフェース):呼び出し側がモジュールを正しく使用するために知る必要があるすべて:型シグネチャだけでなく、不変条件、順序制約、エラーモード、必要な設定、パフォーマンス特性。避けること:API、シグネチャ(狭すぎる、型レベルの表面のみを指す)。

Implementation(実装):モジュールの内部にあるもの、そのコードの本体。「アダプタ」とは区別します。あるものは小さなアダプタで大きな実装を持つ(PostgreSQLリポジトリ)ことも、大きなアダプタで小さな実装を持つ(インメモリフェイク)こともあります。シームが話題のときは「アダプタ」を使い、それ以外は「実装」を使います。

Depth(深さ):インターフェースにおけるレバレッジ。呼び出し側(またはテスト)が学習しなければならないインターフェースの単位あたりに実行できる振る舞いの量。モジュールが深いとは、小さなインターフェースの背後に大量の振る舞いがある場合であり、浅いとは、インターフェースが実装とほぼ同じくらい複雑な場合です。

Seam(シーム)(マイケル・フェザーズ):その場所で編集せずに振る舞いを変更できる場所。モジュールのインターフェースが存在する位置。シームをどこに置くかは、その背後に何を置くかとは別の設計上の判断です。避けること:境界(DDDの境界づけられたコンテキストと重複する)。

Adapter(アダプタ):シームでインターフェースを満たす具体的なもの。役割(どのスロットを埋めるか)を記述し、実体(内部にあるもの)は記述しません。

Leverage(レバレッジ):深さから呼び出し側が得るもの。インターフェースの学習単位あたりの能力が増加します。1つの実装がN個の呼び出しサイトとM個のテストで償却されます。

Locality(局所性):深さから保守者が得るもの。変更、バグ、知識、検証が、呼び出し側に分散するのではなく、一箇所に集中します。一度修正すれば、どこでも修正されます。

深い vs 浅い

ディープモジュール = 小さなインターフェース + 多くの実装:

┌─────────────────────┐
│   小さなインターフェース │  ← 少数のメソッド、単純なパラメータ
├─────────────────────┤
│                     │
│ 深い実装            │  ← 複雑なロジックが隠されている
│                     │
└─────────────────────┘

浅いモジュール = 大きなインターフェース + 少ない実装(避けるべき):

┌─────────────────────────────────┐
│       大きなインターフェース      │  ← 多数のメソッド、複雑なパラメータ
├─────────────────────────────────┤
│  薄い実装                       │  ← 単なるパススルー
└─────────────────────────────────┘

インターフェースを設計するときは、自問してください:

  • メソッドの数を減らせるか?
  • パラメータを単純化できるか?
  • より多くの複雑さを内部に隠せるか?

原則

  • 深さはインターフェースの特性であり、実装の特性ではない。 深いモジュールは内部で小さなモック可能・交換可能な部品から構成されていても構いません。それらは単にインターフェースの一部ではないだけです。モジュールは、内部シーム(実装にプライベートで、自身のテストで使用される)と、インターフェースにある外部シームの両方を持つことができます。
  • 削除テスト。 モジュールを削除することを想像してください。複雑さが消えるなら、それはパススルーでした。複雑さがN個の呼び出し側に再出現するなら、それは存在価値がありました。
  • インターフェースはテスト表面である。 呼び出し側とテストは同じシームを横断します。インターフェースを超えてテストしたい場合、おそらくモジュールの形状が間違っています。
  • 1つのアダプタは仮説上のシームを意味する。2つのアダプタは現実のシームを意味する。 実際に何かがそのシームをまたいで変化しない限り、シームを導入しないでください。

テスト容易性のための設計

良いインターフェースはテストを自然にします:

  1. 依存関係を受け入れ、作成しない。

    // テスト可能
    function processOrder(order, paymentGateway) {}
    
    // テスト困難
    function processOrder(order) {
      const gateway = new StripeGateway();
    }
    
  2. 結果を返し、副作用を生み出さない。

    // テスト可能
    function calculateDiscount(cart): Discount {}
    
    // テスト困難
    function applyDiscount(cart): void {
      cart.total -= discount;
    }
    
  3. 表面積を小さく保つ。 メソッドが少ない=必要なテストが少ない。パラメータが少ない=テストのセットアップが単純。

関係性

  • Moduleは正確に1つのInterfaceを持つ(呼び出し側とテストに提示する表面)。
  • DepthはModuleの特性であり、そのInterfaceに対して測られる。
  • SeamはModuleのInterfaceが存在する場所である。
  • AdapterはSeamに位置し、Interfaceを満たす。
  • Depthは呼び出し側にLeverageを、保守者にLocalityをもたらす。

却下されたフレーミング

  • 深さを実装行数とインターフェース行数の比率とする(Ousterhout):実装を膨らませるインセンティブを与える。代わりにレバレッジとしての深さを使用します。
  • 「インターフェース」をTypeScriptのinterfaceキーワードやクラスのパブリックメソッドとみなす:狭すぎる。ここでのインターフェースには、呼び出し側が知る必要のあるすべての事実が含まれます。
  • 「境界」:DDDの境界づけられたコンテキストと重複する。シームまたはインターフェースと言いましょう。

さらに深く

  • 依存関係を考慮したクラスターの深化、DEEPENING.mdを参照:依存関係のカテゴリ、シームの規律、置き換え・階層化しないテスト。
  • 代替インターフェースの探索、DESIGN-IT-TWICE.mdを参照:並列サブエージェントを起動してインターフェースを根本的に異なる複数の方法で設計し、深さ、局所性、シーム配置を比較する。

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

関連スキル