Trawling

MVC, MVP, MVVM, MVVM-C, VIPER — 다섯 벌의 옷을 입은 하나의 패턴

모바일 앱 아키텍처 논쟁의 고전인 MVC, MVP, MVVM, MVVM-C, VIPER를 'View와 Model 사이의 중재자에게 얼마나 많은 권한과 역할을 줄 것인가'라는 단일 질문의 변형으로 재해석한 글입니다. 프로필 사진 변경이라는 동일한 기능을 다섯 패턴으로 구현하며 각각의 차이와 적합한 상황을 비교합니다.

본문

모바일 팀이라면 누구나 겪는 논쟁이 있습니다. ViewController가 3,000줄을 넘어서면 누군가는 '그냥 MVVM 쓰면 된다'고 말하고, 또 누군가는 VIPER를 꺼내며 회의실이 조용해집니다. 저자는 이 다섯 패턴이 사실 서로 다른 다섯 가지 아이디어가 아니라, 하나의 아이디어가 서로 다른 양의 옷을 입고 있는 것이라고 주장합니다.

세 가지 요소와 계속 이름이 바뀌는 중재자

모든 패턴은 결국 같은 세 가지를 두고 논쟁합니다. 화면을 그리고 터치를 받는 View, 비즈니스 로직과 데이터를 소유하는 Model, 그리고 이 둘이 직접 대화하지 못하게 막는 '번역가'입니다. 이 번역가가 Controller, Presenter, View-Model로 계속 이름을 바꿔 왔고, 나머지 논의는 전부 이 번역가에게 얼마나 권한을 줄지, 그리고 일을 나눠줄 다른 역할이 있는지에 관한 것입니다. MVC는 1970년대 후반 Xerox PARC의 Smalltalk 연구에서 나온, 개인용 컴퓨터만큼이나 오래된 패턴입니다.

같은 기능, 다섯 가지 구현

저자는 '사용자가 프로필 사진을 탭해서 새 사진을 고르는' 동일한 기능을 다섯 패턴으로 실행해 비교합니다. MVC에서는 View가 Controller에 알리고, Controller가 Model을 갱신한 뒤 View에게 다시 그리라고 지시합니다. 화이트보드에서는 깔끔하지만 모든 기능이 Controller라는 유일한 문을 통과하므로, 6개월 뒤에는 컨트롤러가 아니라 회사 모든 부서가 지나다니는 로비가 됩니다. MVP는 부풀어 오른 Controller 문제에 답하기 위해 UI 로직을 전담 Presenter에게 넘기고 View를 의도적으로 멍청하게 만듭니다. Presenter가 View가 구현하는 얇은 인터페이스와만 대화하므로 시뮬레이터 없이도 단위 테스트가 가능하며, 이 테스트 용이성이 MVP를 선택하는 진짜 이유입니다.

MVVM은 Presenter의 수동 '뷰 갱신' 호출을 View와 View-Model 사이의 양방향 데이터 바인딩으로 대체합니다. Model이 바뀌면 바인딩된 View 속성이 자동으로 갱신되어 명시적 refresh 호출이 사라지고, 리액티브 프레임워크와 가장 잘 맞습니다. 보일러플레이트는 줄지만, 버그가 생기면 선형적인 함수 호출이 아니라 자동 알림 체인을 추적해야 하는 전혀 다른 디버깅 기술이 요구됩니다. MVVM-C는 MVVM이 답하지 않는 '화면 전환은 누가 담당하는가'라는 문제를 위해 Coordinator를 추가해 내비게이션을 전담시킵니다. VIPER는 '모두에게 정확히 하나의 일만'이라는 아이디어를 끝까지 밀어붙여 View, Interactor, Presenter, Entity, Router로 나누고, 공유 베이스 클래스 없이 프로토콜만으로 연결합니다. 분리와 테스트 용이성은 최대이지만 프로필 사진 하나 바꾸는 데 파일 수도 최대가 됩니다.

어느 것도 틀리지 않다

저자의 결론은 선택 기준입니다. 출시 속도가 중요한 작은 앱에는 MVC, 중재자를 격리해 테스트해야 하지만 데이터 바인딩이 필요 없다면 MVP, 리액티브 프레임워크로 보일러플레이트를 줄이고 싶다면 MVVM, 내비게이션 흐름까지 중앙화할 가치가 있다면 MVVM-C, 앱과 팀이 모두 커져서 '한 사람 한 역할'이 오버헤드가 아니라 열 명의 엔지니어가 충돌하지 않게 해주는 장치가 되는 시점에 VIPER입니다. 패턴은 아키텍처 그 자체가 아니라, 피하려는 혼란의 크기에 대해 팀이 기꺼이 지불할 의전의 양이라는 것입니다. 실제 고통이 생겼을 때만 업그레이드하고, 가장 작은 것부터 고르라고 조언합니다.

원문: dev.to / 번역·요약: Trawling

참고 자료

오류 제보