배경
초기 6개월 빠른 빌드의 결과로 몇 개 파일이 자기 책임을 다 안고 있었습니다. 가장 무거운 파일이 846줄, 853줄. 신규 기능(그룹 · 문서 · VOD · 노트 · 발표자 모드)을 얹으려고 보면 어디에 넣을지부터 정해야 하는 상태였습니다.
문제는 “코드가 길다”가 아니라 “다음 기능이 들어갈 자리가 없다”였습니다.
접근
도메인 단위로 한 번에 분리했습니다. 회의 도메인은 이벤트 핸들러와 트랙 매니저로 책임을 잘랐고, WebSocket 도메인은 6개 서비스(connection · chat · layout · member · room · track)로 명시했습니다.
회의 본문 컴포넌트는 레이아웃 모드별 훅으로 쪼갰습니다 — grid · pinned · seminar · vad. 어느 모드를 쓸지는 단일 selector 한 곳에서 결정되도록 통합했습니다. 멤버 store는 데이터 슬라이스와 UI 슬라이스로 분리했습니다.
큰 파일을 쪼개는 일은 코드 줄이는 일이 아니라 이름을 붙이는 일이었습니다. 파일 이름을 적는 순간 그 파일이 받아야 할 일과 받지 말아야 할 일이 결정됩니다.
이 작업은 단일 PR에 묶어 한 번에 끝냈습니다. 짧게 여러 번 쪼개는 리팩토링보다 한 번에 그림을 새로 그리는 리팩토링이 도메인 경계를 더 명확하게 만들 때가 있습니다.
결과
- 단일 커밋에서 +2,296 / −1,825 라인 재배치, 신규 파일 13개 생성, 기존 4개 슬림화.
- 846줄 회의 도메인을 이벤트 핸들러와 트랙 매니저로 분리해 슬림화.
- 직후 그룹 · 문서 · VOD · 노트 · 발표자 5개 모드가 추가 모듈화 비용 없이 들어옴.
- 후속으로 다운로드 서비스, 디바이스 store, 구조 최적화 등 책임 분리 4건이 자연스럽게 따라옴.
배운 점
리팩토링의 진짜 메트릭은 직후에 어떤 기능이 어떤 비용으로 들어왔는가입니다. 분리 직후 그룹 · 문서 · VOD · 노트가 한 번도 모듈을 다시 흔들지 않고 그대로 슬롯-인됐다는 사실이, 이름을 잘 붙인 보상이었습니다.