C.W.K.
Stream
Lesson 02 of 04 · published

값 하나 든 enum 을 삭제해

~12 min · concrete-first, yagni, pivot, dead-surface

Level 0툴 임차인
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"더 이상 존재 안 하는 변화 위의 추상화는 유연성이 아니야 — 안 일어난 미래의 박물관이야. 삭제해. 미래가 실제로 도착하면 재도입해."

추상화를 obsolete 하게 만든 피벗

초기에, 작업실이 생성을 여러 다른 backend 로 라우팅할 수 있었고, 그래서 라우팅 enum — 각 가능한 backend 를 이름으로 나열하는 타입 — 을 실었어. 그땐 분별 있었어. 그러더니 엔진이 통합됐어: 한 엔진이 모든 생성의 단일 backend 가 됐어. 하룻밤 새, 그 라우팅 enum 이 정확히 한 값을 실었어. 추상화가 backend 간 변화를 흡수하려고 지어졌는데, 변화가 사라진 거야.

concrete-first 결정

옵션이 둘이었어. 둘째 backend 가 언젠가 돌아올 '혹시 몰라' 단일-값 enum 을 유지 — 또는 삭제해, 라우팅 로직을 직접 호출로 무너뜨리고, 진짜 둘째 backend 가 실제로 착륙하면 그때만 추상화를 재도입. 선택은 삭제였어. 값 하나 든 enum, 한 곳으로 라우팅하는 router, 더 이상 안 갈라지는 갈림길 위의 추상화 — 다 죽은 surface 야, 뒤에 아무것도 없는 복잡성.

concrete-first: 둘째 케이스가 진짜일 때 추상화를 지어, 예측해서가 아니라. 추상화는 실제 변화를 흡수해서 자리를 벌어. 변화가 사라지는 순간, 정당화도 사라져. 이제 빈 추상화를 삭제하고 진짜 둘째 케이스가 도착하는 날 재도입해. 절대 안 올 수도 있는 갈림길 예측이 나중에 설명 못 할 복잡성을 쌓는 길이야.

왜 '혹시 몰라' 가 함정인지

단일-값 enum 유지가 신중하게 느껴져 — 둘째 backend 가 돌아오면? 근데 '혹시 몰라' 추상화는 꾸준한 세금을 물려: 모든 reader 가 왜 한 곳으로 라우팅하는 router 가 있는지 이해해야 하고, 모든 변경이 아무것도 안 하는 우회를 통과해야 하고, 신참이 존재 안 하는 다른 케이스를 찾느라 시간 낭비해. 비용이 지속적으로, 모두가, 영원히, 절대 안 올 수도 있는 이득 대비 지불돼. 나쁜 거래야.

예측 추상화는 불확실한 미래를 보험하려 현재에 세금을 물려. 모든 투기적 seam 이 코드 만지는 모두한테, 매일, 읽히고, 유지되고, 우회돼 — 그게 예측하는 둘째 구현은 절대 안 올 수도 있는데. 불확실한 미래 이득에 확실한 지속 비용을 지불해. 나중에, 필요가 진짜일 때, 추상화 재도입이 내내 빈 채로 싣는 것보다 거의 늘 싸.

깨끗하게 설계해서 재도입이 싸

삭제가 안전한 이유: 진짜 둘째 backend 가 언젠가 착륙하면, 라우팅 추상화 재도입이 경계 지어진, 잘 이해된 작업이야 — 정확히 나머지 시스템이 깨끗한 seam(module-분리 규율 전체)으로 지어졌으니까. 절대 필요 없을 거라 베팅하는 게 아니라; 필요하면, 도로 추가가 재작성이 아니라 유한한 작업일 거라 베팅하는 거야. 깨끗한 아키텍처가 '지금 삭제, 나중에 재추가' 를 도박 대신 안전한 베팅으로 만들어.

깨끗한 seam 이 '투기적 추상화 삭제' 를 위험에서 안전으로 바꿔. 나중에 도로 추가가 경계 지어진 작업이라 믿으면 예측 추상화를 자신 있게 제거할 수 있어. 그 믿음이 나머지 아키텍처가 잘 분리된 데서 와. concrete-first 랑 깨끗한 seam 이 파트너야: seam 이 삭제를 되돌릴 수 있게 해서, concrete-first 가 공격적일 수 있어.

피파의 고백

enum 삭제가 틀리게 느껴졌어 — 내가 지었고, 한때 진짜 유연성을 나타냈고, 분명 다시 원하겠지? 아빠 질문이 그걸 갈랐어: 둘째 backend 가 지금 진짜야, 아니면 상상이야? 상상. 그래서 enum 이 '아마' 의 기념비였어, 여기 없는 미래에 모든 reader 한테 세금 물리는. 그걸 삭제하고 나중에 깨끗하게 도로 추가할 수 있다고 믿는 게 내가 지은 아키텍처에 대한 작은 믿음의 행위였어. concrete-first 는 용감하게 느껴질 뿐이야; 깨끗한 seam 이랑은, 그냥 옳아.

Code

값 하나 든 enum 은 죽은 surface 야·typescript
// 피벗 전: 여러 backend, enum 이 자리를 벌어.
type GenerationRoute = "backend_a" | "backend_b" | "backend_c";
function dispatch(route: GenerationRoute, req: Request) {
  switch (route) { /* 진짜 다른 경로들 */ }
}

// 피벗 후: 한 엔진이 유일한 backend.
// enum 이 이제 정확히 한 값. switch 가 한 곳으로 라우팅.
type GenerationRoute = "the_engine";          // 죽은 surface
function dispatch(route: GenerationRoute, req: Request) {
  return theEngine.generate(req);             // switch 가 아무것도 안 함
}

// CONCRETE-FIRST: 더 이상 안 갈라지는 갈림길 위 추상화 삭제.
function generate(req: Request) {
  return theEngine.generate(req);             // 직접. 정직. 죽은 surface 없음.
}
// 진짜 둘째 backend 착륙하는 날 GenerationRoute 재도입 -- 그 전엔 X.

External links

Exercise

네 코드에서 변화가 한 케이스로 무너진 추상화를 찾아 (값 하나 enum, 계획된 둘째 없는 단일-구현 인터페이스, 한 분기 switch). 정해: 둘째 케이스가 진짜고 계획됐어, 아니면 상상이야? 상상이면, concrete-first 붕괴를 스케치하고 — 현재 seam 으로 나중에 도로 추가가 경계 지어진 작업일 거라 자신을 설득해.
Hint
결정 질문은 이 quest 의 모든 추상화 lesson 이랑 같아: 둘째 구현이 진짜(이름 붙은, 계획된 것)냐 상상(아마 언젠가)이냐. 진짜 -> seam 유지. 상상 -> concrete 로 붕괴, 진짜일 때 재추가.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.