プロパティか、引数か?――設計の迷いを断つ「確定タイミング」の法則

クラス設計において、ある値を「プロパティ(フィールド)」として保持すべきか、それとも「メソッドの引数」として渡すべきか。この選択に、明確な正解がないように思えることがあります。

しかし、ひとつの強力な判断材料があります。それは、「その値が確定するタイミング」と「メソッドが実行されるタイミング」にズレがあるかどうかです。


1. プロパティにすべきは「設定(Configuration)」

値が決まるタイミングが、メソッドを実行するよりも「前」にある場合、それはプロパティとして保持すべきです。

  • ケース: インスタンス化の時点で決まっている情報。
  • 例: APIのベースURL、リトライ回数、タイムアウト秒数、出力先のパス。
  • マインド: そのクラスにとっての「前提条件」や「性格(設定)」です。

判断基準: 「この値は、メソッドを呼び出す『準備』としてあらかじめ知っておくべきことか?」


2. 引数にすべきは「文脈(Context / Input)」

値が決まるタイミングが、メソッドを実行する「その瞬間」である場合、それは引数として渡すべきです。

  • ケース: 実行するたびに中身が変わり得る情報。
  • 例: 検索キーワード、保存対象のデータ、計算の元になる数値。
  • マインド: そのメソッドにとっての「材料」や「今回のリクエスト」です。

判断基準: 「この値は、メソッドを動かす『その時』にならないと分からないことか?」


3. 「タイミングの不一致」が生むアンチパターン

もし、タイミングが「同時」なのにプロパティを使おうとすると、設計が壊れ始めます。

避けるべき「一時的なプロパティ保持」

メソッドを呼ぶ直前にだけプロパティを書き換え、実行後にその値を放置するパターンです。TypeScript

// 悪い例:タイミングが同時なのにプロパティを使っている
class Searcher {
  private keyword: string = "";

  setKeyword(k: string) { this.keyword = k; }

  execute() {
    // this.keyword を使って検索。実行が終わっても残ってしまう。
  }
}
  • なぜダメか: クラスに「意味のない状態」が残り、別のメソッドが誤って参照したり、値が上書きされるリスク(競合)が発生します。
  • 解決策: タイミングが同時なら、素直に execute(keyword: string) とすべきです。

4. まとめ:時間のズレを設計に反映する

設計に迷ったら、そのデータの「鮮度」と「出番」をタイムラインに並べてみてください。

  • インスタンス化 〜 破棄までずっと必要な「知識」プロパティ(コンストラクタで受け取り、不変にする)
  • メソッド呼び出しの瞬間だけ必要な「情報」引数(その場限りで使い切る)

この「タイミングのズレ」を意識するだけで、クラスは驚くほど見通しが良くなり、予期せぬ副作用からも解放されます。

補足

呼び出し側を楽にするためのプロパティ

メソッドを呼び出す側が、その値について知る必要がない(あるいは知るべきではない)場合、それはプロパティとしてクラス内部に保持すべきです。

  • ケース: 内部的なリソースや、実装の詳細に依存する値。
  • 例: データベースの接続プール、キャッシュ用の内部バッファ、APIのシークレットキー。
  • マインド: 呼び出し側には「実行」という目的だけに集中させ、面倒な道具の準備はクラス側で引き受けるという考え方です。

判断基準: 「メソッドを呼ぶたびに、呼び出し側にその値を意識させるのは不親切ではないか?」