iOS 아키텍처 시리즈를 여기까지 따라오셨다면, 이제 선택지는 다 펼쳐졌습니다. MVC, MVVM, MVP, VIPER, 클린 아키텍처, MV, TCA까지요.
그런데 정작 제일 어려운 질문이 남았습니다. “그래서 우리 앱엔 뭘 써야 하죠?”
“정답은 없고 트레이드오프만 있다”는 말은 맞지만, 그것만으로는 아무것도 결정할 수 없죠. 오늘은 시리즈 마지막 편으로, 실제로 결정을 내릴 수 있는 구체적인 기준을 정리해보겠습니다.
기준 1: 팀 규모 — 아키텍처는 사람 문제입니다
아키텍처의 무게는 코드가 아니라 사람 수에 맞추는 게 먼저입니다.
1~2인 팀이라면 구조의 균일함보다 속도가 중요합니다. SwiftUI 기준 MV(Model-View) + Repository 정도면 충분하고, UIKit이라면 MVC에 화면 전환·네트워크만 분리해도 됩니다. 이 규모에서 VIPER(View·Interactor·Presenter·Entity·Router)나 TCA(The Composable Architecture)를 도입하면 구조 유지에 쓰는 시간이 기능 개발을 잡아먹기 쉬워요.
3~10인 팀부터는 “로직이 어디 있는지”에 대한 팀 차원의 합의가 필요해집니다. MVVM + UseCase/Repository가 이 구간의 무난한 표준입니다. 화면마다 구조가 같아야 코드 리뷰와 온보딩 비용이 줄어들거든요.
10인 이상, 여러 스쿼드라면 균일함과 모듈 경계가 최우선입니다. 기능별 모듈화에 클린 아키텍처 계층을 얹거나, 상태 복잡도가 높다면 TCA를 표준으로 삼는 선택이 이 구간에서 나옵니다. VIPER·RIBs가 실제로 채택됐던 것도 이 규모의 조직들이었죠.
기준 2: 앱 수명 — 오래 살 앱일수록 경계에 투자
수명이 짧은 앱(프로토타입, 검증용 MVP(Minimum Viable Product), 행사 앱)에 계층을 쌓는 건 낭비입니다. 빨리 만들고 빨리 배우는 게 목적이니까요.
3년 이상 살아갈 프로덕트라면 이야기가 다릅니다. 그 사이 서버 API는 개편되고, 디자인은 갈아엎어지고, UIKit→SwiftUI 같은 프레임워크 전환도 겪습니다. 이때 값을 하는 건 화려한 패턴이 아니라 경계입니다. 데이터 출처를 숨기는 Repository, 비즈니스 규칙을 담는 UseCase처럼요. 경계가 있으면 부분 교체가 되고, 없으면 전면 재작성이 됩니다.
기준 3: 상태 복잡도 — TCA가 정당화되는 유일한 축
화면 대부분이 “서버에서 받아 보여주고, 입력을 서버로 보내는” 앱이라면 MVVM/MV로 충분합니다. 반면 하나의 상태를 여러 화면이 동시에 편집하거나, 실시간 동기화·오프라인 병합·복잡한 undo가 얽히는 앱이라면, 상태 변경 경로를 강제로 통제하는 TCA의 비용이 정당화되기 시작합니다.
지난 편에서 정리했듯 TCA는 틀린 선택지가 아니라 비싼 선택지입니다. 이 축의 복잡도가 낮다면 그 비용을 회수할 수 없어요.
한 장으로 정리하면
| 상황 | 추천 |
|---|---|
| 혼자·프로토타입 | MV(SwiftUI) 또는 MVC + 최소 분리 |
| 소규모 팀·일반 서비스 앱 | MVVM + Repository (필요 시 UseCase) |
| 레거시 UIKit·바인딩 도입 부담 | MVP + Coordinator |
| 대규모 조직·장수 프로덕트 | 클린 아키텍처 계층 + 기능별 모듈화 |
| 상태 복잡도가 높은 도메인 | TCA (팀의 학습 투자 전제) |
표보다 중요한 건 이겁니다. 이 표의 어느 칸에서 시작하든, 나중에 옆 칸으로 옮길 수 있습니다. 단, 옮길 수 있으려면 조건이 하나 있어요.
어떤 선택을 하든 지켜야 할 불변식
시리즈 전체를 관통한 원칙을 하나로 압축하면 이렇습니다.
View가 네트워크·DB를 직접 만지지 않게 하고, 비즈니스 규칙을 화면 코드 밖에 두세요.
이 불변식만 지켜지면 MVC에서 MVVM으로, MVVM에서 TCA로 옮기는 건 “화면 계층 교체” 문제로 좁혀집니다. 반대로 이게 무너져 있으면 어떤 유행 아키텍처를 도입해도 전면 재작성이 돼요. 아키텍처 이름은 이력서에 남지만, 프로덕트를 살리는 건 경계입니다.
그리고 마지막으로, 아키텍처 전환은 빅뱅이 아니라 새 화면부터 점진적으로 하는 게 정석입니다. 잘 돌아가는 기존 화면을 유행 때문에 갈아엎는 건 대부분 후회로 끝납니다.
시리즈를 마치며
여덟 편을 한 문장씩으로 압축하면 이렇습니다.
- MVC: UIViewController에 책임이 몰리는 구조를 이해하는 것이 출발점
- MVVM: 화면 상태를 빼내고 바인딩으로 동기화, 바인딩 없으면 반쪽
- MVP vs MVVM: 중간 객체가 View를 아는가 모르는가의 차이
- VIPER: 분리의 극단, 유산은 Coordinator와 UseCase로 살아남음
- 클린 아키텍처: 의존성은 안쪽으로만, Repository부터 시작
- TCA: 상태 변경 경로의 통제, 복잡도가 비용을 정당화할 때
- MV 논쟁: 이름이 아니라 로직의 자리와 의존성 방향이 본질
- 선택 가이드: 팀 규모·앱 수명·상태 복잡도로 고르고, 불변식을 지키며 점진 전환
아키텍처는 목적지가 아니라 도구입니다. 팀과 앱이 자라면 갈아탈 수 있게, 경계에 투자해두세요.
