複雑な条件に名前を付ける
複雑な条件式が何の名前もなく使用されると、その条件が意味することを一目で把握するのが難しくなります。
📝 コード例
次のコードは、商品の中でカテゴリーと価格範囲が一致する商品だけをフィルタリングするロジックです。
const result = products.filter((product) =>
product.categories.some(
(category) =>
category.id === targetCategory.id &&
product.prices.some((price) => price >= minPrice && price <= maxPrice)
)
);
👃 コードの不吉な臭いを嗅いでみる
可読性
このコードでは、匿名関数と条件が複雑に絡み合っています。filter
、some
、&&
などのロジックが何重にもなっているため、正確な条件を把握するのが難しくなっています。
コードを読む人が一度に考慮しなければならないコンテキストが多いため、可読性が低下しています。[1]
✏️ リファクタリングしてみる
次のコードのように条件に明示的な名前を付けると、コードを読む人が一度に考慮しなければならないコンテキストを減らすことができます。
const matchedProducts = products.filter((product) => {
return product.categories.some((category) => {
const isSameCategory = category.id === targetCategory.id;
const isPriceInRange = product.prices.some(
(price) => price >= minPrice && price <= maxPrice
);
return isSameCategory && isPriceInRange;
});
});
明示的に同じカテゴリーに属し、価格範囲が一致する商品でフィルタリングするように書くことで、複雑な条件式を追わなくてもコードの意図を明確に示すことができます。
🔍 さらに詳しく: 条件式に名前を付ける基準
いつ条件式や関数に名前を付けて分離するのが良いのでしょうか?
条件に名前を付けるべき時
複雑なロジックを扱う時: 条件文や関数で複雑なロジックが複数行にわたって処理される場合、名前を付けて関数の役割を明確にしたほうが良いです。こうすることによってコードの可読性が向上し、保守やコードレビューが容易になります。
再利用性が必要な時: 同じロジックを複数の場所で繰り返し使用する可能性がある場合、変数や関数を宣言して再利用できます。これによりコードの重複を減らし、保守が容易になります。
単体テストが必要な時: 関数を分離すると、独立して単体テストを作成できます。単体テストは関数が正しく動作しているかを簡単に確認でき、特に複雑なロジックをテストする際に有効です。
条件に名前を付けなくても良い時
ロジックが簡単な時: ロジックが非常に簡単な場合は、わざわざ名前を付ける必要はありません。例えば、配列の要素を単に 2 倍にする
arr.map(x => x * 2)
のようなコードは、名前を付けなくても直観的です。一度だけしか使用しない時: 特定のロジックがコード内で一度だけ使用され、そのロジックが複雑でない場合、匿名関数で直接ロジックを処理する方が直観的かもしれません。