DRY 原則

Don't Repeat Yourself の略で、知識の重複を排除し、単一の正を維持する設計原則

設計設計原則

DRY 原則とは

DRY (Don't Repeat Yourself) は、Andy Hunt と Dave Thomas が『達人プログラマー』(1999 年) で提唱した原則で、「すべての知識はシステム内で唯一の、曖昧さのない、正式な表現を持つべき」とする。単なるコードの重複排除ではなく、知識の重複を排除する原則。

コードの重複 vs 知識の重複

// ❌ コードが同じだが、知識は異なる (DRY 違反ではない)
function validateAge(age: number) { return age >= 0 && age <= 150; }
function validateQuantity(qty: number) { return qty >= 0 && qty <= 150; }
// 年齢と数量は別の知識。たまたま同じ条件でも共通化すべきでない

// ❌ コードは異なるが、知識が重複 (DRY 違反)
const TAX_RATE = 0.1;  // config.ts
const tax = price * 0.1; // order.ts ← 0.1 がハードコード

DRY の適用例

// ❌ 知識の重複: バリデーションルールが 2 箇所に
// フロントエンド
if (name.length < 1 || name.length > 50) { ... }
// バックエンド
if (name.length < 1 || name.length > 50) { ... }

// ✅ 共通の定義を共有
// shared/validation.ts
export const NAME_RULES = { minLength: 1, maxLength: 50 } as const;

DRY の過剰適用 (WET)

// ❌ 過剰な DRY: 無理に共通化して複雑に
function processEntity(type: 'user' | 'order' | 'product', data: any) {
  if (type === 'user') { /* ... */ }
  else if (type === 'order') { /* ... */ }
  else if (type === 'product') { /* ... */ }
}
// 3 つの異なるロジックを 1 つの関数に押し込んでいる

// ✅ 適切な分離
function processUser(data: UserData) { /* ... */ }
function processOrder(data: OrderData) { /* ... */ }

DRY vs WET vs AHA

DRY は知識の重複を排除する原則だが、WET (Write Everything Twice) は 2 回までの重複を許容し、AHA (Avoid Hasty Abstractions) は早すぎる抽象化を避ける。3 つの原則はバランスの問題で、DRY を過度に追求すると不自然な抽象化が生まれる。

DRY の適用範囲

対象
ビジネスルール 税率、バリデーション
設定値 環境変数、定数
スキーマ定義 TypeScript の型から JSON Schema を生成
IaC CloudFormation の Mappings, Conditions

CloudFormation での DRY

Mappings:
  EnvConfig:
    dev:
      LogLevel: DEBUG
    prod:
      LogLevel: WARN

# 1 箇所で定義、複数箇所で参照
Environment:
  Variables:
    LOG_LEVEL: !FindInMap [EnvConfig, !Ref Environment, LogLevel]

DRY 原則を扱う関連書籍も多い。

関連用語