Files
2nd/10_Wiki/Topics/AI_and_ML/Dry-Principle.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

236 lines
6.5 KiB
Markdown

---
id: wiki-2026-0508-dry-principle
title: DRY Principle (Don't Repeat Yourself)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [DRY, Don't Repeat Yourself, single source of truth, WET, AHA]
duplicate_of: none
source_trust_level: A
confidence_score: 0.98
verification_status: applied
tags: [software-engineering, principles, dry, clean-code, abstraction, refactoring]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Universal
applicable_to: [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
```python
# 매 ❌ 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)
```typescript
// 매 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)
```typescript
const config = {
apiUrl: process.env.API_URL ?? 'http://localhost:3000',
timeout: Number(process.env.TIMEOUT ?? 5000),
};
// 매 single config object, env-specific override
```
### OpenAPI codegen
```yaml
# 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
```typescript
// 매 schema 의 ORM model 의 single source
@Entity()
class User {
@PrimaryColumn() id: string;
@Column({ unique: true }) email: string;
}
// 매 migration 의 generate from model
```
### Template (Mustache / Liquid)
```handlebars
{{!-- email-template.hbs --}}
Hi {{user.name}}, your order #{{order.id}} ships {{order.shipDate}}.
```
### Inheritance / mixin (cautious)
```python
class TimestampMixin:
created_at: datetime
updated_at: datetime
class User(Base, TimestampMixin): pass
class Post(Base, TimestampMixin): pass
```
### Decorator (cross-cutting)
```python
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
```python
# 매 ❌ 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)
```bash
# 매 jscpd
npx jscpd --threshold 5 --reporters html src/
# 매 reports clones >= 5 lines
```
### Refactor — Pull Up Method
```python
# 매 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)
```python
# 매 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
- 부모: [[Software-Engineering-Principles]] · [[Clean-Code]]
- 변형: [[AHA]] · [[Rule-of-Three]] · [[Single-Source-of-Truth]]
- 응용: [[Refactoring_Best_Practices|Refactoring]] · [[Codegen]]
- Adjacent: [[SOLID]] · [[YAGNI]] · [[KISS]] · [[Conventional-Commits]]
## 🤖 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 |