DRY原則
DRY Principle
概要(サマリー)
DRY原則(Don't Repeat Yourself)は、システム内で同じ知識やロジックを複数の場所に重複して持たないようにする設計原則である。
日本語では「重複排除の原則」と説明されることが多い。たとえば、同じ計算式、同じ設定値、同じ入力チェック、同じビジネスルールがあちこちにコピペされていると、あとから変更するときに修正漏れが起きやすくなる。
DRY原則は、単に「似たコードを減らそう」という話ではない。「このルールの正しい情報源はどこか」を1箇所に集め、変更するときにそこだけ直せばよい状態を目指す考え方である。
詳細解説
DRY原則とは何か
DRYは「Don't Repeat Yourself」の略で、「自分自身を繰り返すな」という意味である。
ここで繰り返してはいけないものは、コードの文字列だけではない。計算ルール、業務上の判断、設定値、データの定義、エラーメッセージの管理方針など、システムが持っている「知識」全体が対象になる。
たとえば、消費税率を複数のファイルに 0.1 と直接書いていると、税率が変わったときに全箇所を探して直す必要がある。1箇所でも修正を忘れると、画面によって計算結果が違うというバグにつながる。
DRY原則に従うと、このような知識を定数、関数、設定ファイル、データベース設計などに集約し、変更点をできるだけ1箇所に閉じ込める。
なぜ重複が問題になるのか
重複したコードや設定は、最初は便利に見える。既存のコードをコピーして少し直せば、すぐに動くものが作れるからである。
しかし、時間が経つと重複は保守の負担になる。たとえば、同じ入力チェックが3箇所にある場合、ルール変更時には3箇所すべてを直さなければならない。
重複が増えると、次のような問題が起きやすい。
- 修正漏れによって、画面ごとに挙動がずれる
- どれが正しい実装なのか分からなくなる
- 同じバグを複数箇所で直す必要が出る
- コード量が増え、読む負担が大きくなる
- AIや人間が既存処理を見落として、さらに似た処理を増やす
つまりDRY原則は、見た目をきれいにするためだけのルールではない。変更に強く、長く保守できるシステムにするための考え方である。
DRY違反のコード例
次の例では、消費税率と税込価格の計算が複数の関数に重複している。
DRY違反の例
function calculateCartTotal(price) {
const taxRate = 0.1;
const tax = price * taxRate;
return price + tax;
}
function calculateShippingTotal(price) {
const taxRate = 0.1;
const tax = price * taxRate;
const shippingFee = 500;
return price + tax + shippingFee;
}
このコードでは、税率 0.1 と「価格に税金を足す」という計算ルールが重複している。もし税率や計算方法が変わった場合、両方の関数を修正しなければならない。
DRY原則に沿ったコード例
DRY原則に沿うなら、税込価格を計算する処理を1箇所にまとめる。
DRY原則に沿った例
const TAX_RATE = 0.1;
function calculateTaxIncludedPrice(price) {
return price + price * TAX_RATE;
}
function calculateCartTotal(price) {
return calculateTaxIncludedPrice(price);
}
function calculateShippingTotal(price) {
const shippingFee = 500;
return calculateTaxIncludedPrice(price) + shippingFee;
}
この形にしておけば、税込価格の計算ルールを変えるときは calculateTaxIncludedPrice だけを直せばよい。税率のような値も定数として1箇所に置くことで、マジックナンバーを減らせる。
このように、DRY原則はソースコードを読みやすくし、変更時のミスを減らすために役立つ。
DRY原則はコード以外にも関係する
DRY原則は、コードだけに限らない。システム内で同じ情報が複数の場所にあるなら、それはDRY違反になり得る。
たとえば、次のような場面でもDRYの考え方が使われる。
- 同じ設定値を複数ファイルに書かず、設定ファイルや環境変数にまとめる
- 同じデータを複数テーブルに保存せず、データベース設計を整理する
- API仕様書とコードがずれないよう、スキーマから自動生成する
- 同じUI部品を画面ごとに作らず、共通コンポーネントにする
- 同じ手順を手作業で繰り返さず、スクリプトやCI/CDで自動化する
「同じことを何度も人間が覚えて、何度も手で直す」状態を減らすのがDRYの実務的な価値である。
共通化しすぎると逆に読みにくくなる
DRY原則は重要だが、何でも共通化すればよいわけではない。
たまたま今の見た目が似ているだけで、将来は別々の理由で変わる処理を無理に1つにまとめると、かえって修正しにくくなる。片方だけ変えたいのに、もう片方にも影響してしまうからである。
たとえば、管理者用の入力チェックと、一般ユーザー用の問い合わせフォームの入力チェックが今は似ていても、将来の変更理由は別かもしれない。この2つを早い段階で無理に共通化すると、片方の仕様変更がもう片方を壊す可能性がある。
DRY原則で大切なのは、「コードの見た目が似ているか」ではなく、「同じ知識を表しているか」を見ることである。同じ知識ならまとめる。別の知識なら、似ていても分けておく判断が必要である。
AIコーディングとの関係
AIコーディングでは、DRY原則を意識することがかなり重要である。AIは指示された範囲だけを見てコードを生成することがあり、既存の共通関数や設定を使わずに、似た処理を新しく作ってしまう場合がある。
たとえば、「この画面にも同じバリデーションを追加して」とだけ依頼すると、AIは既存のバリデーション関数を探さず、その場に新しい入力チェックを書くことがある。短期的には動いても、あとから同じルールが複数箇所に散らばる原因になる。
AIに依頼するときは、次のように伝えるとよい。
既存の共通関数やユーティリティがあれば再利用してください。
同じロジックを新しく書き足さず、必要なら共通関数として切り出してください。
DRY原則に反する重複がないかも確認してください。
また、AIにリファクタリングを依頼する場合は、単に「重複をなくして」ではなく、「読みやすさを落とさない範囲で」「将来別々に変わりそうな処理は無理に共通化しないで」と添えるとよい。
DRY原則は、AIが出したコードをレビューする観点としても役立つ。「同じ処理が増えていないか」「既存の関数で代用できないか」「同じ設定値が散らばっていないか」を見るだけでも、コードの品質は上げやすい。
よくある勘違い
DRY原則はコピペを完全禁止するルール?
DRY原則は、コピペを一切してはいけないという単純なルールではない。
学習中や試作中には、まず似たコードをコピーして動きを理解することもある。問題は、そのまま本番コードに残し、同じ知識が複数箇所に散らばった状態を放置することである。
動く形を作ったあとで、共通化できる部分を見直す。この流れでも十分にDRY原則へ近づける。
見た目が似ているコードは全部まとめるべき?
見た目が似ているだけで共通化すると、かえって扱いにくくなることがある。
DRY原則でまとめるべきなのは、同じ意味・同じルール・同じ変更理由を持つコードである。将来別々に変わる可能性が高いものは、似ていても分けたままにする方が安全な場合がある。
DRYにすれば必ず読みやすくなる?
必ずしもそうではない。共通化しすぎると、処理を理解するために複数のファイルや関数を行き来しなければならなくなる。
読みやすさと重複削減は、バランスを取る必要がある。少しの重複を許した方が分かりやすい場合もあるため、「重複を消すこと」自体を目的にしすぎないことが大切である。
まとめ
- DRY原則は、同じ知識やロジックを複数箇所に重複させないための設計原則である。
- 重複を減らすと、仕様変更時の修正漏れやバグを防ぎやすくなる。
- 対象はコードだけでなく、設定、データ設計、ドキュメント、作業手順にも広がる。
- 見た目が似ているだけのコードを無理に共通化すると、逆に変更しにくくなることがある。
- AIコーディングでは、既存処理の再利用と重複チェックを明示的に指示するとよい。