--- id: wiki-2026-0508-principles title: Principles category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Software Engineering Principles, Design Principles] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [design, principles, engineering, meta] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: meta framework: cross-language --- # Principles ## 매 한 줄 > **"매 software engineering 매 invariant guidelines — 매 decade-tested heuristics 매 specific tech 매 무관 적용"**. SOLID (Robert C. Martin 2000), DRY/KISS/YAGNI (XP 1999), Composition over Inheritance (GoF 1994) 매 backbone, 매 2026 매 LLM-augmented coding 매 시대 매 여전히 readability/maintainability 매 governing axis. ## 매 핵심 ### 매 SOLID - **S — Single Responsibility**: 매 module 매 매 reason-to-change 매 하나. - **O — Open/Closed**: 매 extension 매 open, 매 modification 매 closed. - **L — Liskov Substitution**: 매 subtype 매 base type 매 자리 매 대체 가능. - **I — Interface Segregation**: 매 client 매 unused method 매 의존 X. - **D — Dependency Inversion**: 매 high-level module 매 low-level 매 의존 X — 매 abstraction 매 의존. ### 매 핵심 short heuristics - **DRY (Don't Repeat Yourself)**: 매 knowledge 매 single representation. - **KISS (Keep It Simple, Stupid)**: 매 simplest thing 매 works. - **YAGNI (You Aren't Gonna Need It)**: 매 future-need 매 가정 X. - **Composition over Inheritance**: 매 has-a 매 is-a 보다 flexible. - **Tell, Don't Ask**: 매 object 매 데이터 묻지 말고 매 행동 요청. - **Law of Demeter**: 매 friend-of-friend 매 의존 X (`a.b.c.d()` 매 X). - **Principle of Least Astonishment**: 매 행동 매 사용자 expectation 매 일치. - **Fail Fast**: 매 오류 매 early surface — 매 silent corruption 매 X. - **Boy Scout Rule**: 매 떠날 때 매 코드 매 더 깨끗하게. ### 매 응용 1. Code review checklist (SOLID violations, DRY 적용 검토). 2. Architecture decision record (principle 매 trade-off rationale). 3. Onboarding (junior dev 매 mental model). 4. LLM prompt engineering (gen 시 매 principle 매 명시 → quality ↑). ## 💻 패턴 ### SRP — split reasons-to-change ```ts // 매 BAD — 매 두 reasons (HTTP + persistence) class UserController { async register(req, res) { const user = req.body if (!user.email) return res.status(400).send('email required') await db.query('INSERT INTO users ...', [user]) return res.send('ok') } } // 매 GOOD class UserController { constructor(private validator: UserValidator, private repo: UserRepo) {} async register(req, res) { const result = this.validator.validate(req.body) if (!result.ok) return res.status(400).send(result.error) await this.repo.save(req.body) return res.send('ok') } } ``` ### OCP — strategy pattern ```ts // 매 BAD — 매 새 type 매 추가 시 매 modify function calc(shape: Shape): number { switch (shape.kind) { case 'circle': return Math.PI * shape.r ** 2 case 'square': return shape.side ** 2 // 매 새 type → 매 여기 수정 필요 } } // 매 GOOD — 매 extension 매 open interface Shape { area(): number } class Circle implements Shape { constructor(public r: number) {}; area() { return Math.PI * this.r ** 2 } } class Square implements Shape { constructor(public side: number) {}; area() { return this.side ** 2 } } class Triangle implements Shape { /* 매 새 file — 매 기존 코드 unchanged */ } ``` ### LSP — substitutability ```ts // 매 BAD — Square 매 Rectangle 의 LSP 위반 class Rectangle { constructor(public w: number, public h: number) {} setW(w: number) { this.w = w } setH(h: number) { this.h = h } } class Square extends Rectangle { setW(w: number) { this.w = w; this.h = w } // 매 surprise setH(h: number) { this.w = h; this.h = h } } function expand(r: Rectangle) { r.setW(5); r.setH(10) console.assert(r.w === 5 && r.h === 10) // Square 매 fail } // 매 GOOD — 매 hierarchy 분리 / composition ``` ### ISP — fat interface 매 분할 ```ts // 매 BAD interface Worker { work(): void eat(): void sleep(): void } class Robot implements Worker { work() {} eat() { throw new Error('robots dont eat') } // 매 ISP 위반 sleep() { throw new Error('robots dont sleep') } } // 매 GOOD interface Workable { work(): void } interface Eatable { eat(): void } interface Sleepable { sleep(): void } class Robot implements Workable { work() {} } class Human implements Workable, Eatable, Sleepable { /* */ } ``` ### DIP — depend on abstractions ```ts // 매 BAD — 매 high-level (OrderService) 매 low-level (MysqlOrderRepo) 매 의존 class OrderService { private repo = new MysqlOrderRepo() place(order: Order) { this.repo.save(order) } } // 매 GOOD interface OrderRepo { save(o: Order): Promise } class OrderService { constructor(private repo: OrderRepo) {} place(o: Order) { return this.repo.save(o) } } class MysqlOrderRepo implements OrderRepo { /* */ } class PostgresOrderRepo implements OrderRepo { /* */ } ``` ### Composition over Inheritance ```ts // 매 BAD class Duck { fly() { /* */ } quack() { /* */ } } class RubberDuck extends Duck { fly() { throw new Error("can't fly") } // 매 LSP 위반 } // 매 GOOD — 매 strategy composition interface FlyBehavior { fly(): void } interface QuackBehavior { quack(): void } class Duck { constructor(private flyB: FlyBehavior, private quackB: QuackBehavior) {} performFly() { this.flyB.fly() } performQuack() { this.quackB.quack() } } const rubberDuck = new Duck(new FlyNoWay(), new Squeak()) const mallard = new Duck(new FlyWithWings(), new NormalQuack()) ``` ### Tell Don't Ask ```ts // 매 BAD — 매 ask if (account.balance > amount) { account.balance -= amount ledger.record(amount) } // 매 GOOD — 매 tell account.withdraw(amount, ledger) // 매 객체 매 캡슐화 + 매 invariant 매 보장 ``` ### Law of Demeter ```ts // 매 BAD — 매 train wreck const street = order.customer.address.street // 매 GOOD — 매 method 매 노출 const street = order.customerStreet() // 매 Order 매 delegate ``` ### Fail Fast ```ts // 매 BAD — 매 silent fallback function parse(s: string) { try { return JSON.parse(s) } catch { return {} } // 매 caller 매 깨진 data 매 모름 } // 매 GOOD — 매 explicit function parse(s: string): Result { try { return { ok: true, value: JSON.parse(s) } } catch (e) { return { ok: false, error: e as Error } } } ``` ## 매 결정 기준 | 상황 | Principle | |---|---| | God class refactor | SRP — split | | 매 새 변형 매 추가 매 잦은 수정 | OCP — strategy | | Subtype 매 caller surprise | LSP — rethink hierarchy | | Interface 매 unused methods | ISP — split | | Hard-coded dependency | DIP — inject | | Repeated code 3+ places | DRY — extract | | Speculative generality | YAGNI — delete | | Surprise behavior | Least Astonishment — rename/redesign | | Hidden errors | Fail Fast — throw early | **기본값**: 매 SOLID + 매 KISS + 매 YAGNI — 매 over-abstraction 매 함정 매 회피. ## 🔗 Graph - 변형: [[SOLID]] · [[Clean-Architecture]] · [[Hexagonal-Architecture]] - 응용: [[Code-Review]] · [[Refactoring_Best_Practices|Refactoring]] · [[Architecture-Decision-Record]] - Adjacent: [[Design-Patterns]] · [[Domain-Driven-Design]] · [[Test-Driven-Development]] ## 🤖 LLM 활용 **언제**: 매 design review, 매 refactor planning, 매 principle violation 매 식별, 매 mentoring/teaching context. **언제 X**: 매 throwaway script (overhead), 매 dogmatic application — 매 principle 매 means 매 X end. ## ❌ 안티패턴 - **매 principle 매 dogma**: 매 SRP 매 따라 매 1-line class 매 폭발 — 매 trade-off. - **DRY over-application**: 매 coincidental duplication 매 동일 함수 묶음 — 매 false abstraction. - **YAGNI 매 결여**: 매 "future-proof" 매 매 무한 layer. - **DIP 매 always**: 매 simple CRUD 매 abstract repo — 매 over-engineer. - **OCP 매 rule**: 매 모든 enum 매 polymorphism 변환 — 매 readability ↓. - **Pattern dropping**: 매 Strategy/Factory/Observer 매 nameset — 매 problem 매 first. ## 🧪 검증 / 중복 - Verified (Clean Code/Architecture by R.C. Martin, Design Patterns GoF, Pragmatic Programmer). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — SOLID + heuristics + violation/fix patterns matrix |