Files
2nd/10_Wiki/Topics/AI_and_ML/Dry-Principle.md
T
koriweb d8a80f6272 chore(wiki): dangling 링크 canonical 정규화 (768파일/1200건)
이름만 다른(표기 변형) [[위키링크]]를 대상 문서의 canonical 제목으로 치환해
끊겼던 1,200개 링크를 연결. 제목/파일명 정규화 일치만 적용하고 별칭 매칭은
과병합 위험으로 제외(애매성 가드). 원본은 _link_reconcile_backup/ 에 백업.
도구: Datacollect/scripts/link_reconcile_apply.mjs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 12:24:15 +09:00

6.5 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-dry-principle DRY Principle (Don't Repeat Yourself) 10_Wiki/Topics verified self
DRY
Don't Repeat Yourself
single source of truth
WET
AHA
none A 0.98 applied
software-engineering
principles
dry
clean-code
abstraction
refactoring
2026-05-10 pending
language applicable_to
Universal
Code
Schema
Config
Documentation

DRY Principle

매 한 줄

"매 every piece of knowledge 의 single, unambiguous, authoritative representation". Hunt & Thomas (Pragmatic Programmer). 매 duplication = 매 update bug. 매 modern caveat: 매 AHA (Avoid Hasty Abstraction) — 매 too-early DRY 의 wrong abstraction. 매 rule: 매 3rd repetition 의 abstract.

매 핵심

매 origin

  • Hunt & Thomas, Pragmatic Programmer (1999).
  • 매 "knowledge" 의 emphasize — 매 code line 의 X.

매 vs WET / AHA

  • WET: Write Everything Twice / We Enjoy Typing.
  • AHA: Avoid Hasty Abstraction (Sandi Metz).
  • Rule of 3: 매 3 repetition 의 abstract.
  • Quote: "Duplication is far cheaper than the wrong abstraction." — Sandi Metz.

매 type of duplication

  • Imposed: 매 environment 의 force.
  • Inadvertent: 매 unaware.
  • Impatient: 매 deadline.
  • Interdeveloper: 매 communication 의 X.

매 응용

  1. Constants: 매 magic number 의 named.
  2. Functions: 매 logic 의 extract.
  3. Templates / generics: 매 type 의 abstract.
  4. Schema: 매 single source.
  5. Config: 매 env-specific override.
  6. Doc: 매 generate from code.

매 modern context

  • Microservices: 매 service 의 own data → 매 controlled duplication.
  • CQRS: 매 read / write model 의 separate.
  • Type-driven: 매 schema 의 source.
  • Codegen: 매 OpenAPI → client / server.
  • LLM era: 매 context-aware 의 inline 의 fine (token cost).

💻 패턴

Extract function

# 매 ❌ duplicated
def order_total(items):
    total = 0
    for i in items: total += i.price * i.qty
    tax = total * 0.08
    return total + tax

def cart_total(cart):
    total = 0
    for i in cart: total += i.price * i.qty
    tax = total * 0.08
    return total + tax

# 매 ✅ DRY
def calculate_total(items, tax_rate=0.08):
    subtotal = sum(i.price * i.qty for i in items)
    return subtotal * (1 + tax_rate)

Single source of truth (schema)

// 매 Zod schema → 매 type + 매 validation
import { z } from 'zod';
const UserSchema = z.object({ id: z.string(), email: z.string().email() });
type User = z.infer<typeof UserSchema>;
// 매 runtime validation + compile-time type

Config (env override)

const config = {
  apiUrl: process.env.API_URL ?? 'http://localhost:3000',
  timeout: Number(process.env.TIMEOUT ?? 5000),
};
// 매 single config object, env-specific override

OpenAPI codegen

# openapi.yaml — single source
paths:
  /users/{id}: { get: { responses: { 200: { schema: { $ref: '#/User' } } } } }

# 매 → openapi-typescript / openapi-generator → client + server stubs + docs

Database migration as code

// 매 schema 의 ORM model 의 single source
@Entity()
class User {
  @PrimaryColumn() id: string;
  @Column({ unique: true }) email: string;
}
// 매 migration 의 generate from model

Template (Mustache / Liquid)

{{!-- email-template.hbs --}}
Hi {{user.name}}, your order #{{order.id}} ships {{order.shipDate}}.

Inheritance / mixin (cautious)

class TimestampMixin:
    created_at: datetime
    updated_at: datetime

class User(Base, TimestampMixin): pass
class Post(Base, TimestampMixin): pass

Decorator (cross-cutting)

def retry(times=3):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for attempt in range(times):
                try: return func(*args, **kwargs)
                except: if attempt == times - 1: raise
        return wrapper
    return decorator

@retry(times=3)
def fetch_data(url): ...

AHA — when NOT to abstract

# 매 ❌ premature abstraction
class GenericResourceHandler:
    def __init__(self, kind, ...18 params...): ...

# 매 ✅ duplicate first, abstract later
def handle_user(req): ...
def handle_post(req): ...
# 매 → 매 3rd similar handler 의 의 emerge 의 pattern 의 see → 매 then abstract

Detect duplication (PMD / jscpd)

# 매 jscpd
npx jscpd --threshold 5 --reporters html src/
# 매 reports clones >= 5 lines

Refactor — Pull Up Method

# 매 before
class Dog:
    def name(self): return self._name
class Cat:
    def name(self): return self._name

# 매 after
class Animal:
    def name(self): return self._name
class Dog(Animal): pass
class Cat(Animal): pass

Pragmatic limit (microservices)

# 매 service A
class UserDTO_A: id: str; email: str

# 매 service B (separate codebase)
class UserDTO_B: id: str; email: str

# 매 ✅ controlled duplication — 매 services 의 independent deploy
# 매 ❌ shared library 의 coupling 의 anti-pattern

매 결정 기준

상황 DRY Rule
2nd occurrence Wait
3rd occurrence Extract
Cross-service Controlled duplicate
Schema Single source + codegen
Config Env-override
Wrong abstraction Inline first

기본값: 매 rule of 3 + 매 AHA (avoid hasty abstraction) + 매 wrong abstraction > duplication.

🔗 Graph

🤖 LLM 활용

언제: 매 refactor. 매 abstraction decision. 매 code review. 언제 X: 매 < 3 occurrence. 매 cross-domain.

안티패턴

  • Premature DRY: 매 wrong abstraction → 매 update 의 cascade.
  • Inheritance abuse: 매 IS-A 의 X 의 force.
  • Cross-service shared lib: 매 deploy coupling.
  • DRY at all cost: 매 readability < deduplication.
  • Magic abstraction: 매 reader 의 confuse.

🧪 검증 / 중복

  • Verified (Pragmatic Programmer, Sandi Metz).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-04-20 Auto-reinforced
2026-05-08 Phase 1
2026-05-10 Manual cleanup — DRY + AHA + 매 extract / Zod / OpenAPI / detect / refactor code