--- id: wiki-2026-0508-clean-code-principles title: Clean Code Principles category: 10_Wiki/Topics status: verified canonical_id: self aliases: [clean code, SOLID, DRY, KISS, YAGNI, Robert Martin, Uncle Bob, naming, function rules] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [clean-code, solid, dry, kiss, refactoring, software-craftsmanship, naming, code-quality] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: language-agnostic framework: any --- # Clean Code Principles ## πŸ“Œ ν•œ 쀄 톡찰 > **"λ§€ code 의 communication 의 tool"**. λ§€ machine 보닀 λ§€ future-self / λ§€ colleague. Robert Martin (Uncle Bob) 의 catalog κ°€, λ§€ dogma 의 risk. λ§€ modern AI μ‹œλŒ€ 의 maintainability 의 even more critical. ## λ§€ 핡심 principle ### Naming - **Intention-revealing**: `daysSinceLastLogin` > `d`. - **Searchable**: λ§€ unique enough. - **Pronounceable**: λ§€ conversation 의 κ°€λŠ₯. - **Avoid mental mapping**: `i` 의 single-letter 의 OK 만 λ§€ small loop. ### Function - **Small** (Fowler: <10 line ideal). - **Do one thing**. - **Single level of abstraction**. - **Few argument** (0-3, ideally <2). - **No side effect** (or λ§€ λͺ…μ‹œμ ). - **No flag argument** (boolean β†’ λ§€ 별도 function). ### SOLID (5 principles) 1. **S β€” Single Responsibility**: λ§€ 1 reason to change. 2. **O β€” Open/Closed**: λ§€ extend 의 OK, λ§€ modify 의 X. 3. **L β€” Liskov Substitution**: λ§€ subclass 의 swap 의 OK. 4. **I β€” Interface Segregation**: λ§€ small + focused interface. 5. **D β€” Dependency Inversion**: λ§€ abstraction 의 depend, λ§€ concrete X. ### Other - **DRY** (Don't Repeat Yourself). - **KISS** (Keep It Simple, Stupid). - **YAGNI** (You Aren't Gonna Need It). - **POLA** (Principle of Least Astonishment). - **Boy Scout Rule** (better than found). - **Composition over inheritance**. ### λ§€ critique (Casey Muratori, others) - λ§€ over-abstraction. - λ§€ small function 의 maze. - λ§€ SOLID 의 mechanical 적용 의 bad design. - λ§€ dogma 의 trap. β†’ λ§€ principle 의 intent 의 understand. λ§€ mechanical 적용 X. ### λ§€ modern context - λ§€ AI-generated code 의 review 의 base. - λ§€ LLM 의 sometimes good naming, λ§€ sometimes verbose. - λ§€ comment 의 LLM 의 over-add 의 trim. ## πŸ’» νŒ¨ν„΄ ### Naming (TS) ```ts // ❌ Bad const d = new Date(); const ut = users.filter(u => u.lt < d - 30); // βœ… Good const today = new Date(); const inactiveUsers = users.filter(u => u.lastLoginDate < addDays(today, -30) ); ``` ### Function size ```ts // ❌ Long function function processOrder(order) { // λ§€ 50 line: validate, calculate tax, calculate shipping, // apply discount, save to db, send email, log audit... } // βœ… Decomposed function processOrder(order) { validate(order); const total = calculateTotal(order); persist(order, total); notify(order); audit(order); } ``` ### SRP (Single Responsibility) ```ts // ❌ Multiple responsibility class User { save() { db.save(this); } sendEmail() { mailer.send(this.email, ...); } hashPassword() { ... } validateInput() { ... } } // βœ… Separated class User { ... data ... } class UserRepository { save(user) { db.save(user); } } class UserMailer { send(user, ...) { mailer.send(user.email, ...); } } class PasswordHasher { hash(plain) { ... } } class UserValidator { validate(input) { ... } } ``` ### OCP (Open/Closed) ```ts // ❌ Modify on each new shape function area(shape) { if (shape.type === 'circle') return Math.PI * shape.r ** 2; if (shape.type === 'square') return shape.side ** 2; // λ§€ μƒˆ shape 의 add β†’ λ§€ modify } // βœ… Extend (polymorphism) interface Shape { area(): number; } class Circle implements Shape { area() { ... } } class Square implements Shape { area() { ... } } // λ§€ μƒˆ shape 의 add β†’ λ§€ μƒˆ class. ``` ### Dependency Inversion ```ts // ❌ Concrete dependency class OrderService { private db = new PostgresDatabase(); save(order) { this.db.save(order); } } // βœ… Abstraction interface Database { save(item): void; } class OrderService { constructor(private db: Database) {} save(order) { this.db.save(order); } } ``` ### DRY (carefully) ```ts // ❌ Duplicate function calcRetailPrice(p) { return p * 1.1 * 0.95; } function calcWholesalePrice(p) { return p * 1.1 * 0.85; } // βœ… Extract function applyTaxAndDiscount(price, discount) { return price * 1.1 * (1 - discount); } // ⚠️ But: λ§€ too eager DRY β†’ premature abstraction. // "Two cases that look similar may have different reasons. // Wait for 3rd duplicate before abstracting." ``` ### YAGNI ```ts // ❌ Speculative class User { constructor(public id, public email, public preferences = new Preferences()) {} // λ§€ preferences 의 미래 use 의 expect β€” λ§€ currently unused. } // βœ… Add when needed class User { constructor(public id, public email) {} } // λ§€ future 의 add when needed. ``` ### Comment (when truly needed) ```ts // ❌ Redundant // λ§€ increments i i++; // ❌ Outdated // λ§€ returns user list (actually returns IDs now) function getUsers() { return ids; } // βœ… Reason / non-obvious // λ§€ Use legacy auth path due to bug #1234 (waiting for upstream fix). // λ§€ Delete after 2026-12 (when fix lands). ``` ### ESLint config (clean code) ```json { "rules": { "complexity": ["error", 10], "max-lines-per-function": ["warn", 50], "max-params": ["warn", 4], "max-depth": ["warn", 4], "no-magic-numbers": ["warn", { "ignore": [0, 1, -1] }], "id-length": ["warn", { "min": 2, "exceptions": ["i", "j", "_"] }] } } ``` ### Boy Scout Rule (programmatic) ```python # λ§€ PR 의 review μ‹œ 의 leave-better-than-found def pr_smell_check(diff): smells_in_changed = detect_smells(diff) if smells_in_changed > 0: suggest('Touched code has smells. Consider small cleanup in this PR.') ``` ## πŸ€” κ²°μ • κΈ°μ€€ | 상황 | Approach | |---|---| | New feature | KISS + YAGNI | | Long function | Extract Method | | Many params | Parameter Object | | Inheritance trap | Composition | | Cross-cutting | Strategy / decorator | | Magic number | Named constant | | Duplicate (3rd time) | Extract | | Unclear name | Rename refactor | **κΈ°λ³Έκ°’**: λ§€ SOLID 의 intent 의 understand + λ§€ boy scout. λ§€ dogma X. ## πŸ”— Graph - λΆ€λͺ¨: [[Refactoring_Best_Practices|Refactoring]] - λ³€ν˜•: [[SOLID]] Β· [[DRY]] Β· [[KISS]] Β· [[YAGNI]] - μ‘μš©: [[Code_Smells]] Β· [[Refactoring_Best_Practices|Refactoring]] Β· [[Clean-Architecture]] - λΉ„νŒ: [[Anaemic Domain Model]] - Adjacent: [[Architecture Anti-patterns]] Β· [[Quality_Code_Review_Modern]] Β· [[Software Architecture Styles]] ## πŸ€– LLM ν™œμš© **μ–Έμ œ**: λ§€ review. λ§€ refactor. λ§€ onboarding. λ§€ AI-generated code 의 quality check. **μ–Έμ œ X**: λ§€ prototype (premature). λ§€ simple script. ## ❌ μ•ˆν‹°νŒ¨ν„΄ - **Dogma**: λ§€ λͺ¨λ“  code 의 mechanical 적용. - **Over-abstraction**: λ§€ SOLID 의 imitate 의 bad design. - **Premature DRY**: λ§€ wrong abstraction. - **Over-decomposition**: λ§€ small function 의 maze. - **Comment 의 over-add**: λ§€ LLM 의 typical. - **No measurement**: λ§€ better 의 prove X. ## πŸ§ͺ 검증 / 쀑볡 - Verified (Robert Martin "Clean Code", Fowler "Refactoring", Beck "Implementation Patterns"). - 신뒰도 A (with caveats β€” λ§€ not gospel). - Related: [[Code_Smells]] Β· [[SOLID]] Β· [[Software Architecture Styles]] Β· [[Refactoring_Best_Practices|Refactoring]]. ## πŸ•“ Changelog | λ‚ μ§œ | λ³€κ²½ | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup β€” naming + SOLID + critique + λ§€ ESLint code |