DRYは、Don’t Repeat Yourself の略です。
直訳すると「同じことを繰り返すな」ですが、ここでいう「同じこと」は、見た目が似ているコードだけを指すわけではありません。
一言でいうと
DRYは、同じ知識や同じ変更理由を複数箇所に散らばらせないための原則です。
たとえば、送料計算のルールが3つの画面に別々に書かれていると、送料ルールが変わったときに3箇所を直す必要があります。1箇所でも直し忘れると、画面ごとに違う計算結果になります。
このような状態が、DRY違反です。
重複コードと重複知識の違い
初心者が間違えやすいのは、「似たコードがあったら全部まとめる」と考えることです。
| 種類 | 例 | 対応 |
|---|---|---|
| 重複知識 | 同じ税率、同じ料金ルール、同じ権限判定 | 共通化を検討する |
| たまたま似た形 | ユーザー登録とイベント予約の入力チェック | すぐ共通化しない |
| 一時的な重複 | 仕様が固まる前の試作コード | 変化を見てから判断する |
重要なのは、コードの見た目ではなく、変更理由です。
悪い例
function showCartTotal(price: number) {
const tax = price * 0.1;
return price + tax;
}
function createInvoice(price: number) {
const tax = price * 0.1;
return price + tax;
}
税率が2箇所にあります。税率が変わると、両方を直す必要があります。
よい例
const TAX_RATE = 0.1;
function calculateTaxIncludedPrice(price: number) {
return price + price * TAX_RATE;
}
税率という知識を1箇所に集めました。これなら変更漏れが起きにくくなります。
何でも共通化すればよいわけではない
次のようなコードは、見た目は似ています。
function validateUserName(name: string) {
return name.length >= 2;
}
function validateProductName(name: string) {
return name.length >= 2;
}
今は同じ条件でも、ユーザー名と商品名は将来別々のルールになるかもしれません。この段階で validateName にまとめると、片方だけ変えたいときに苦しくなります。
DRYは「似ているコードを必ずまとめる」ではありません。
共通化してよいサイン
- 同じ仕様変更で同時に変わる
- 同じ業務ルールを表している
- 片方だけ変わる可能性が低い
- 名前を付けると意味が明確になる
- テストも同じ観点で書ける
共通化した名前が自然に決まるなら、抽象化してよい可能性が高いです。
共通化を待つべきサイン
- 似ている理由を説明できない
- 片方だけ変わる未来が見える
- 引数や分岐が増えすぎる
- 共通関数名が
handleDataのように曖昧になる - 呼び出し側を読むより共通関数を読む方が難しい
この場合は、重複を少し残しても構いません。
まとめ
DRY原則は、同じ知識を複数箇所に書かないための考え方です。見た目が似ているだけのコードを急いでまとめると、かえって変更しにくくなります。
共通化する前に、「この2つは同じ理由で変わるのか」を確認しましょう。