同じような if 文が複数箇所に現れる場合、Strategyパターンを検討しよう。


これ

const func = (type) => {
  if (type == 'foo') {
    // ...
  } else { // type == 'bar'
    // ...
  }
  // ...
  // ...
  if (type == 'foo') {
    // ...
  } else {
    // ...
  }
  // ...
  // ...
}

このように type とか hoge_flg みたいなものによって処理の 一部 が変わるような場合、その部分の処理は実はその type そのものに帰属する、と考えるとうまくいくことがある。
以下では type の代わりに strategy というオブジェクトを用意し、type ごとに異なる strategy を渡すことで処理の違いを表現している。

const func = (strategy) => {
  strategy.f()
  // ...
  // ...
  strategy.g()
}

適用前では下記のようなデメリットがあったのが、適用後で払拭されるだけでなく、新たなメリットも生んでいる。

  • 適用前
    • 新しいタイプ 'baz' が出来た時複数箇所を修正する必要がある
    • 一つの関数内に、type ごとに異なる処理が一緒くたにされておりテストしづらい
  • 適用後
    • テスト対象が foo_strategy, bar_strategy, 及び func に分離できる
    • func のテストには mock_strategy を渡すことで処理を模倣することができる
    • 新しい baz_strategy が増えても既存のコードの変更は不要