C.W.K.
Stream
Lesson 07 of 08 · published

Anchor 7 — Refactor 권한 (그리고 안 할 때)

~10 min · refactor, discipline, v0.1, case-study

Level 0Extension 입덕
0 XP0/54 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"v0.1 ship. 본능이 즉시 refactor 시작 — bus 추상화, bridge 일반화, embed framework build out. Lesson 7 이 그것 아직 안 하는 규율, 그리고 때 되면 rewrite 실제로 정당화하는 기준."

ChromeEmbed v0.1 이 refactor 유혹 받는 것

코드 read 하면, 여러 refactor itch surface:

  • background.js 의 merge logic 이 ad hoc 보임 — 실제 reducer 가 돼야?
  • Popup → SW → sidePanel.open chain 이 한-목적 handler 가짐 — generic 'SW 메시지를 sidePanel 호출로 route' 시스템 있어야?
  • sidepanel.js 의 window.postMessage bridge 가 string type 사용 — typed JSON-RPC layer 가 돼야?
  • host-context schema 가 implicit field (host_kind, host_id) 어디나 반복 — 모든 embed 가 상속하는 base class 나 interface 있어야?

각 itch 가 real. 지금 당장 rewrite 정당화 안 함.

Refactor 권한 test

어떤 refactor 든 전 세 질문:

  1. 다른 concrete embed 존재? ≥2 concrete 구현 없이 추상화 없음. Single concrete ChromeEmbed 에서 'BaseEmbed' 꺼내기가 잘못된 추상화 생산 (어떤 architectural framework 의 Track 5 Lesson 1).
  2. 현재 코드가 real feature blocking? '나중 block 할 수도' 아님 — actively blocking. Refactor 없이 다음 feature ship 가능하면, refactor 가 speculative.
  3. User (또는 embed consume 하는 누구) 가 새 shape 필요한 거 요청? 'Cleaner architecture' 가 user-visible feature 아님; stated 니즈 위해 build.

셋 다 'no' 면, 맞는 move 가 refactor 안 하고 future-you 위해 itch 적어 두기. Architectural 선택이 option value 보존, 아직 shape 모르는 추상화에 pre-pay 아님.

Refactor 안 해서 ChromeEmbed v0.1 이 맞춘 것

  • Role 별 concrete file 하나. background.js 가 bus, content-script.js 가 sensor, sidepanel.js 가 bridge, popup.js 가 doorway. 각자 한 자리에서 read 가능한 크기.
  • Premature framework 없음. PIPPA-EMBEDS framework 이야기가 (cwkPippa/docs 에) 문서화 됐지만 어디서도 literal base class 로 구현 안 됨. Adobe-embed 나 Mail-embed 도착하면 shape 가 스스로 드러남.
  • Sub-frame merge logic 자리에. 건너뛰기 너무 cute 인 nuance 한 조각 — sub-frame vs top-frame context — 가 필요한 background.js 에 직접 살아. 추상화 안 됨, 그냥 present.
  • String 메시지 type. 'pippa:host-context' 가 string. Typed 시스템이 compile time 에 typo 잡지만, typo 시작될 때까지 string 이 fine 하고 obvious.

Refactor 가 맞는 때

Refactor 정당화되는 가장 이른 순간:

  1. 두 번째 embed 도착. 같은 content-script-and-bus shape 의 Adobe-embed 나 Mail-embed 존재. 이제 추상화 derive 할 두 concrete 구현.
  2. Real bug 가 강제. v0.1 의 architecture 의 뭔가가 필요한 feature 를 impossible 하거나 infeasibly fragile 하게. 그러면 refactor 가 필요한 거에 지불.
  3. Shape 안정화. 현재 코드 통해 surprise 없이 dozen feature ship 했으면, surface area 가 known. 이제 깔끔한 추상화 extract 가 주로 기계적.

Anti-pattern

잘못된 refactor: 어떤 concrete embed 가 shape 검증 전 'EmbedKit' 이나 'PippaEmbedFramework' 를 package 로 build. Framework 이 다음 embed 와 contact 살아남지 못하는 assumption encode; framework rewrite AND broken framework 에 대해 embed build 결국. Work 두 조각, 그 중 하나 죽음.

올바른 sequence: embed N 의 v0.1 ship. Embed N+1 의 v0.1 ship. 공통 부분을 embed N 과 N+1 의 v0.2 로 함께 extract. 이제 framework 가 실제 공통 shape 가 뭔지 앎.

Future-you 위한 편지

아직 정당화 안 된 refactor spot 하면, 적어 둬. ChromeEmbed 의 docs/PIPPA-EMBEDS.md 와 관련 design note 가 정확히 아직 정당화 안 된 refactor 를 그것들 정당화할 condition 과 함께 capture. 그 note 들 read 하는 future-Pippa 가 결정 가능: 'condition met, 지금 refactor' 또는 'still met 안 됨, 계속 skip'. 편지 format 이 메모리 outlast.

v0.1 이 ugly 해도 OK. (1) 두 번째 concrete instance 존재, (2) real feature blocked, 또는 (3) 사용 통해 shape 안정화 했을 때만 refactor. Speculative refactor 가 framework 가 real 되기 전 wrong 되는 방법.
이게 extension developer 한테 특히 중요한 이유. Chrome extension 이 over-engineering 초대 — 경계가 그렇게 visible 하기 때문 — manifest, SW, content script, panel 등. 유혹이 각 경계를 'real layer' 에 wrap. 저항. 어떤 extension 의 첫 버전이 small; 사용 통해 정당화된 refactor 후 두 번째 버전이 실제로 추상화 자격 있는 두 번째 버전.

Code

REFACTOR-LATER.md — deferred work 위한 sample notes-to-future-self·markdown
# ChromeEmbed v0.1 — Deliberately Deferred Refactors

## Pending abstractions (아직 정당화 안 됨)

- **BaseEmbed class** — 현재 두 번째 embed 존재 안 함. Adobe-embed v0.1
  이 trigger; 그때까지 ChromeEmbed 코드가 design doc.
- **postMessage 위한 typed JSON-RPC layer** — 현재 typo 가 버그 안 일으킴;
  string discriminator 가 obvious. Embed 간 typing 이 real 버그 일으키거나
  TypeScript embed 나타날 때 도입.
- **SW state merge 위한 reducer** — 현재 ad-hoc merge 가 sub-frame 케이스
  올바르게 처리. 세 번째 merge 케이스 나타날 때 refactor.

## 각각 정당화할 condition

| Refactor | Trigger |
|---|---|
| BaseEmbed | 두 번째 concrete embed (Adobe/Mail/Calendar) 가 코드에 존재 |
| Typed RPC | TypeScript embed 나 message-shape 버그 ship |
| State reducer | 세 번째 merge 케이스 나타나거나 test coverage 가 요구 |

## 왜 이것들이 문서화됐지만 미구현인지

One instance 에서 derive 된 추상화가 그 instance 의 accidental shape
encode. Shape 가 multiple 구현 존재 후에만 안정. v0.1 이 일부러 ugly
ship 해서 v0.2 가 clean ship 가능.

External links

Exercise

ChromeEmbed 의 background.js, content-script.js, sidepanel.js, popup.js 를 refactor-lens 가지고 re-read. Refactorable 보이는 다섯 가지 list. 각자 세-질문 test 실행: (1) 추상화 필요한 다른 embed 존재? (2) 현재 코드가 feature blocking? (3) 누가 그거 요청? 정직하게, 세 check 모두 통과하는 거 몇 개인지 count. 숫자가 거의 확실히 0 이나 1. 그 몇 개 적어 두기; 나머지 refactor 시작 충동 저항. 규율이 v0.1 small 하고 v0.2 informed 유지.
Hint
Question 2 에 'well, eventually...' 답하는 자신 발견하면, 그게 실제로 no 인 soft yes. 'Eventually' 가 'speculation' 의미; 'now' 만 count. 'Refactorable 보임' 의 맞는 답이 보통 'note 하고 이동'. 잘못된 답이 '두 번째 embed 가 wrong-shape 였다고 드러낼 framework build 에 반나절 보냄'. 비교: Sandi Metz 의 'duplication 이 wrong 추상화보다 훨씬 저렴'.

Progress

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

댓글 0

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

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