制御結合

結合度の一種。呼び出し元がフラグやモード値を渡し、呼び出し先がその値によって処理分岐を変えるパターン。

問題点

本質:制御所有の位置

制御結合の問題はif文の存在ではなく、制御所有の位置にある。

// 悪い例:呼び出し側が分岐を制御
function process(data: Data, mode: "sync" | "async") {
  if (mode === "sync") { /* ... */ }
  else { /* ... */ }
}
process(data, "sync"); // 呼び出し側が内部実装を知っている

解決策:ポリモーフィズム

ポリモーフィズムを使うと、制御の責任が「呼び出し」から「構築」に移動する。

// 良い例:構築時に型を決定
interface Processor { process(data: Data): void; }
class SyncProcessor implements Processor { /* ... */ }
class AsyncProcessor implements Processor { /* ... */ }

const processor = new SyncProcessor(); // 構築時に決定
processor.process(data); // 呼び出し時はフラグ不要

判別共用体との関係

判別共用体のtype属性は、使い方によって制御結合にもデータ結合にもなりうる:

境界層(腐敗防止層)で一度だけ分岐を吸収し、内部は宣言的に実装するのが現実的な解決策。

関連

参照