共通化は便利です。重複を減らし、変更箇所を少なくできます。
しかし、共通化しすぎるとコードは読みにくくなります。特に初心者は「重複を消すこと」だけを目的にして、かえって保守しにくいコードを作りがちです。
一言でいうと
共通化は、同じ変更理由を持つコードにだけ使うべきです。
似ているだけのコードをまとめると、あとで片方だけ変えたいときに、共通関数へ条件分岐が増えていきます。
共通化しすぎた例
function validateText(
value: string,
min: number,
max: number,
allowSymbol: boolean,
allowSpace: boolean,
) {
if (value.length < min) return false;
if (value.length > max) return false;
if (!allowSymbol && /[!-/:-@]/.test(value)) return false;
if (!allowSpace && value.includes(" ")) return false;
return true;
}
一見便利そうですが、何のための関数か分かりにくくなっています。
ユーザー名、商品名、カテゴリ名、コメント本文を全部この関数で処理しようとすると、引数が増えます。仕様変更のたびに条件が追加され、誰も全体を把握できなくなります。
分けたほうがよい例
function validateUserName(name: string) {
return name.length >= 2 && name.length <= 20 && !name.includes(" ");
}
function validateProductName(name: string) {
return name.length >= 1 && name.length <= 80;
}
コード量は少し増えます。しかし、目的がはっきりしています。ユーザー名の仕様変更は validateUserName だけを見ればよいです。
早すぎる抽象化とは
早すぎる抽象化とは、まだ変化の方向が分からない段階で、先回りして共通部品を作ることです。
| 状態 | 起きやすい問題 |
|---|---|
| 2箇所だけ似ている | 実は別々に変わる |
| 将来使いそうで共通化 | 結局使われない |
| 汎用関数を作る | 引数と分岐が増える |
| 名前が曖昧 | 呼び出し側の意図が読めない |
共通化は、未来を当てる作業ではありません。実際に同じ変更が繰り返されてからでも遅くない場合が多いです。
Rule of Three
実務では「3回目に共通化を考える」という目安があります。
1回目は普通に書きます。2回目は様子を見ます。3回目に同じ形と同じ変更理由が見えたら、共通化を検討します。
これは絶対ルールではありませんが、早すぎる抽象化を防ぐよい目安です。
共通化の判断基準
- 同じ仕様変更で同時に変わるか
- 共通化後の名前は具体的か
- 引数が増えすぎていないか
- 条件分岐で利用元を区別していないか
- 共通化前より読みやすいか
特に、共通関数の中に type === "user" のような分岐が増えたら注意です。それは共通化ではなく、責務の詰め込みになっている可能性があります。
まとめ
共通化は、重複を減らすための手段です。しかし、似ているだけのコードを急いでまとめると、変更に弱い巨大な共通関数になります。
共通化するか迷ったら、「同じ理由で変わるか」「名前を具体的に付けられるか」を確認しましょう。