- 모듈 경계를 나누는 기준이 무엇인가요?
- Interface/Implementation 분리가 왜 빌드를 빠르게 합니까?
- static과 dynamic 링킹의 트레이드오프는? 실무에선 어떻게 씁니까?
- 모듈을 100개로 쪼개면 무조건 좋아지나요?
모듈 경계를 나누는 기준 🔥 핵심
가장 흔한 오답이 "레이어별로 나눈다"입니다 — View 모듈, ViewModel 모듈, Model 모듈처럼요. 이렇게 나누면 기능 하나를 고칠 때 모듈 세 개를 동시에 건드리게 됩니다. 경계가 변경을 막아주지 못합니다.
실무 기준은 하나로 압축됩니다 — "함께 변경되는 것끼리 묶고, 따로 변경되는 것은 나눈다." 모듈 경계는 변경의 경계여야 합니다. 이 원칙의 원전은 Parnas 1972 — 모듈을 나누는 기준에서 다룹니다.
Interface / Implementation 분리 🔥 핵심
각 기능을 FeatureInterface(프로토콜만)와 FeatureImplementation(실제 코드) 두 타깃으로 나눕니다.
다른 모듈은 Interface에만 의존하고, Implementation은 앱을 조립할 때만 연결합니다.
왜 빌드가 빨라지는가
이게 면접에서 갈리는 지점입니다. "모듈로 나누면 병렬 빌드가 되니까"는 절반만 맞는 답입니다. 더 큰 효과는 재컴파일 전파 범위가 줄어드는 것입니다.
공짜가 아닙니다. 프로토콜 + 구현 + 조립 코드로 보일러플레이트가 늘고, 조립 지점(앱 타깃 또는 DI 컨테이너)에 복잡도가 집중됩니다. "그래서 어디에 복잡도를 몰았나요?"가 자연스러운 꼬리질문입니다.
static vs dynamic 링킹
Xcode 15 / iOS 15+의 Mergeable Libraries는 이 절충을 자동화합니다. 개발 중에는 동적 프레임워크로 두어 증분 빌드를 살리고, 릴리즈 빌드에서 하나로 병합해 dyld 로드 비용을 없앱니다.
앱 시작 시간 — 모듈 수가 영향을 주는 곳 🧩 롱테일
"동적 프레임워크가 많으면 시작이 느려진다"는 말의 실체는 main()이 불리기 전 단계에 있습니다.
| 개선 항목 | 구체적 조치 |
|---|---|
| dyld 로드 | 동적 프레임워크 수 축소 · static 전환 · Mergeable Libraries |
| ObjC 런타임 | +load 대신 +initialize 또는 지연 초기화 |
| 초기화 코드 | 서드파티 SDK 초기화를 첫 화면 이후로 미루기 |
| 첫 화면 | 시작 경로에서 동기 네트워크·디스크 I/O 제거 |
과분할 — 많이 쪼갤수록 좋은 게 아니다 🔥 핵심
모듈화를 해본 사람인지 아닌지가 가장 확실하게 드러나는 질문이 "모듈을 100개로 쪼개면 무조건 좋나요?"입니다. 정답은 아니오이고, 이유를 셋 이상 대야 합니다.
| 과분할의 대가 | 왜 생기나 |
|---|---|
| 링크 시간 증가 | 링커가 처리할 산출물 수가 늘어남 |
| 그래프 생성 지연 | Tuist가 프로젝트를 생성하는 시간 자체가 늘어남 |
| 앱 시작 지연 | 동적 프레임워크라면 dyld 로드가 개수만큼 누적 |
| 개발 경험 악화 | 한 기능 고치는데 모듈 3~4개를 오가야 함 |
| 경계의 의미 상실 | 항상 같이 바뀌는 모듈이라면 나눠도 아무것도 못 막음 |
합칠 기준도 하나로 말할 수 있어야 합니다 — "항상 함께 변경되고 독립적으로 배포되지 않는 모듈은 다시 합친다."