--- id: wiki-2026-0508-inversion title: Inversion category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Inversion of Control, Invert Thinking, Negative Visualization] duplicate_of: none source_trust_level: A confidence_score: 0.85 verification_status: applied tags: [thinking-model, ioc, di, mental-model, design] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: typescript framework: nestjs --- # Inversion ## 매 한 줄 > **"매 problem 의 reverse 매 stating — '매 fail 하는 방법' 의 enumerate, '매 control 의 누가 가지나' 의 flip"**. 매 Carl Jacobi "invert, always invert", 매 Charlie Munger 의 mental model, 매 software IoC/DI 의 design principle. ## 매 핵심 ### 매 Inversion 3 layer - **Cognitive**: "매 success" 대신 "매 failure 의 path" 을 enumerate. - **Architectural (IoC)**: caller 가 control 하던 것을 framework 가 control. - **Dependency (DI)**: hard-coded `new Foo()` 대신 inject. ### 매 IoC 의 forms - **DI**: constructor/setter inject. - **Service Locator**: registry lookup. - **Events/Hooks**: publish-subscribe. - **Template Method**: framework 의 skeleton, user 의 fill-in. ### 매 응용 1. Design review: failure mode enumeration. 2. Testability: mock injection. 3. Decision making: 매 worst case 의 list, 매 avoid. ## 💻 패턴 ### NestJS DI ```ts @Injectable() export class UserRepo { findById(id: string) { /* ... */ } } @Injectable() export class UserService { // 매 instance 매 직접 만들지 않음 — framework 의 inject constructor(private readonly repo: UserRepo) {} async profile(id: string) { return this.repo.findById(id); } } @Module({ providers: [UserRepo, UserService], exports: [UserService] }) export class UserModule {} ``` ### Manual DI (no framework) ```ts type Deps = { db: Database; cache: Cache; logger: Logger }; export const makeUserService = ({ db, cache, logger }: Deps) => ({ async findById(id: string) { const cached = await cache.get(id); if (cached) return cached; logger.debug('cache miss', id); return db.users.findUnique({ where: { id } }); } }); ``` ### Premortem (failure inversion) ```ts // scripts/premortem.ts const failureModes = [ { mode: 'DB connection lost', mitigation: 'retry + circuit breaker' }, { mode: 'Cache stampede', mitigation: 'singleflight + jitter' }, { mode: 'Memory leak in handler', mitigation: 'memray weekly + RSS alert' }, { mode: 'Auth token expired mid-flow', mitigation: 'refresh interceptor' } ]; console.table(failureModes); ``` ### Test seam via inversion ```ts // 매 hard-coded fetch 대신 inject — testable type Fetcher = (url: string) => Promise; export const makeApi = (fetcher: Fetcher = fetch) => ({ async get(path: string) { const r = await fetcher(`https://api.acme.com${path}`); return r.json(); } }); // test const fakeFetch: Fetcher = async () => new Response(JSON.stringify({ ok: true })); expect(await makeApi(fakeFetch).get('/x')).toEqual({ ok: true }); ``` ### Hook-based extension (template inversion) ```ts // framework 의 lifecycle, user 의 hook 의 plug type Plugin = { beforeRequest?: (req: Request) => Request; afterResponse?: (res: Response) => Response; }; export class Server { private plugins: Plugin[] = []; use(p: Plugin) { this.plugins.push(p); } async handle(req: Request) { for (const p of this.plugins) req = p.beforeRequest?.(req) ?? req; let res = await this.process(req); for (const p of this.plugins) res = p.afterResponse?.(res) ?? res; return res; } } ``` ### Inverted error handling (Result type) ```ts // 매 throw 대신 매 return 으로 invert — caller 의 forced handle type Result = { ok: true; value: T } | { ok: false; error: E }; export async function fetchUser(id: string): Promise> { try { const u = await db.users.findUniqueOrThrow({ where: { id } }); return { ok: true, value: u }; } catch (e) { return { ok: false, error: e as Error }; } } ``` ### Decision premortem prompt ```ts // 매 launch 전 self-question const premortem = ` 1. 매 launch 6 month 후, 이 기능 매 fail 했다고 가정. 2. 매 가장 가능한 5 failure cause 매 무엇? 3. 매 매 cause 의 mitigation 매 무엇? `; ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Module 매 testable 만들기 | DI | | Framework 의 design | IoC + plugin hooks | | Decision making | Premortem (failure inversion) | | Error handling | Result type (return invert) | **기본값**: constructor DI + premortem 매 architecture review 시. ## 🔗 Graph - 부모: [[Mental_Models|Mental Models]] · [[Software Design Principles]] - 변형: [[Dependency Injection]] · [[Inversion of Control]] - 응용: [[NestJS]] · [[Result Type]] - Adjacent: [[Encapsulation-via-Access-Modifiers]] · [[Testability]] ## 🤖 LLM 활용 **언제**: 매 design 의 failure mode 의 brainstorm, IoC refactor 의 candidate 식별. **언제 X**: 매 trivial pure function 의 매 over-DI X — 매 simplicity 가 우선. ## ❌ 안티패턴 - **DI everywhere**: simple value 도 inject → 매 boilerplate explosion. - **Service locator hell**: global registry 의 hidden dependency. - **No premortem**: 매 ship 후에야 매 failure 발견. - **Inversion theater**: interface 매 single impl 만 — 의 wrap 의 무의미. ## 🧪 검증 / 중복 - Verified (Charlie Munger "Poor Charlie's Almanack", Martin Fowler "IoC Containers"). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — cognitive + IoC + DI inversion 통합 |