コンテンツにスキップ

判断ガイド: インターフェースを作るべきか

判断フロー

Q1. 実装は今いくつある? 2つ目は「確定した予定」か?
    → 1つで予定も曖昧 ──> 作らない(具象クラスを直接使う)…ただしQ2へ
Q2. テストで差し替えたい依存か?(I/O・時間・乱数・ネットワーク・課金)
    → はい ──> 作る(実装1つでもテスト用フェイクが2つ目の実装)
    → いいえ ──> Q3へ
Q3. 呼び出し側と実装側を、別々に変更・ビルド・配布したい境界か?
   (モジュール境界、チーム境界、DLL境界、エンジン非依存層)
    → はい ──> 作る
    → いいえ ──> 作らない。必要になった日に抽出すればよい(安い作業)

根拠: ポリモーフィズムDIPISPYAGNI

判断材料

  • 作るシグナル: 実装が既に2つ(または2つ目が今期の計画にある)/モック無しでテストが書けない/#include連鎖がビルドを苦しめている境界(前方宣言では足りない場合)
  • 作らないシグナル: 「いつか差し替えるかも」以外の理由が言えない/インターフェース名が IEnemyManager のように実装名の頭にIを付けただけ(抽象の語彙が生まれていない → DIPの「抽象の所有」)

例外

  • 公開API・プラグイン境界: 実装が1つでも最初からインターフェースにする(外部に具象を晒すと後から変えられない——可逆性の原則の例外側)
  • ホットループの内側: テスト差し替えのためでも、毎フレーム数万回呼ぶ箇所に仮想関数を挟むのは要計測(→ テンプレートか仮想関数か)

トレードオフ

  • 得: 差し替え・テスト・ビルド分離・依存方向の制御
  • 失: 間接1段(実行時+読解時)、「定義へ移動」がインターフェースに飛ぶ迷路、ファイル数、抽象の設計責任(下手な抽象は具象より害 → 実装1つの段階では良い抽象を設計する材料が足りない、が「後で抽出」推奨の本当の理由)

実践のコツ

  • 後からの抽出は安い: 具象クラスの利用箇所を「その関数シグネチャのまま」インターフェースに置き換えるのはIDE支援でほぼ機械作業。「後で抽出できる形」=具象のpublic APIを小さく保つことが、前倒しの抽象より価値がある
  • 作るときはISP: 呼び出し側が使う分だけの小さい顔で

理解度チェック

  1. 実装が1つでもインターフェースを作る2条件は?
  2. 「頭にIを付けただけの抽象」の何が問題ですか。
  3. 「後で抽出」が安い前提条件は?

前: クラスを分けるべきか | カテゴリ目次 | 次: 継承かコンポジションか