pile·
모바일·티몬티몬·

MVC-MVVM-VIPER로 이어지는 앱 개발 구조패턴(2)

MVC와 MVVM으로 이어지던 앱 구조 패턴 연재의 2부로 VIPER를 다룬다. 앞 글에서 남긴 세 가지 질문, 즉 API 호출을 어디서 하고 화면 전환을 어떻게 다루며 중복 코드를 어떻게 막을지에 대한 답으로 VIPER를 놓는다. 티몬이 실제로 라우터 개념만 떼어 적용한 사례가 마지막에 붙는다.

핵심 포인트
  • VIPER는 View, Interactor, Presenter, Entity, Router 다섯 역할로 나눈다.
  • Interactor가 비즈니스 로직과 API 호출을 맡고 그 결과로 모델을 만든다.
  • Presenter는 Interactor에 데이터를 요청하고 받은 것을 View에 어떻게 그릴지 지시한다.
  • Router는 화면 전환 로직을 전담하며 이것이 모바일에 특화된 지점이다.
  • 역할이 늘어 복잡해 보이지만 단일 책임 원칙에 더 충실한 구조가 된다.
  • 티몬은 전체 도입 대신 라우터 개념만 가져와 화면 전환 로직을 한 곳으로 모았다.
상세 정리
  • 앞 글이 남긴 질문: API를 호출할 일이 많은데 어디서 부를지, 화면이 많은데 그냥 호출하면 되는지, 같은 화면을 여러 곳에서 각각 push하면 중복 코드가 쌓이지 않을지였다.
  • View의 역할: Presenter가 보여주려는 것을 화면에 그리고 사용자 입력을 Presenter로 넘긴다.
  • Interactor의 역할: 비즈니스 로직을 갖고 API에서 데이터를 받아 엔티티를 만든다.
  • Presenter의 역할: Interactor에 데이터를 요청해 받고 뷰 로직을 가지며 무엇을 어떻게 그릴지 View에 알린다.
  • Entity의 역할: Interactor가 만들어내는 모델이다.
  • Router의 역할: 내비게이션 로직을 담당하며 화면에서 화면으로 넘어가는 부분을 처리한다.
  • 정리하면: API 관련 코드는 Interactor로, 뷰 로직은 Presenter로, 화면 이동은 Router로 보낸다.
  • 프로토콜 구성 팁: 하나의 화면에서 쓰는 프로토콜을 한 곳에 모아두면 보기 편하다고 조언한다.
  • 프로토콜 예시: Router에는 모듈 조립과 화면 표시, View에는 표시와 에러 메시지, Presenter에는 진입 시점과 버튼 동작, Interactor에는 입력용 조회와 출력용 성공·실패 콜백을 둔다.
  • Router 구현: 스토리보드에서 뷰컨트롤러를 만들고 Presenter와 Interactor, Router 인스턴스를 생성해 서로 참조를 연결한 뒤 완성된 화면을 반환한다.
  • 조립의 의미: 각 구성요소의 생성과 연결이 한 자리에 모여 있어 의존 관계가 눈에 보인다.
  • View 구현: Presenter를 소유하고 진입 시점과 버튼 이벤트를 그대로 Presenter에 넘기며, 표시 관련 메서드는 확장으로 구현한다.
  • Presenter 구현: View는 약한 참조로, Interactor와 Router는 강한 참조로 갖고, 진입 시점에는 조회를 요청하고 버튼 동작에는 화면 전환을 요청한다.
  • Presenter의 출력 처리: 조회 실패면 에러 메시지를, 성공이면 받은 데이터를 보관하고 View에 표시를 지시한다.
  • Interactor 구현: 네트워크 라이브러리로 API를 호출하고 응답을 모델로 바꿔 출력 쪽으로 넘긴다.
  • 구조에 대한 평가: 구성요소가 늘어 복잡해 보일 수 있지만 앞선 두 패턴보다 세분화돼 단일 책임 원칙에 충실하고, 내비게이션 로직이 추가된 점이 모바일에 특화된 부분이다.
  • 티몬의 적용: 전체를 도입하는 대신 라우터와 같은 개념으로 내비게이션 로직을 하나로 정리해 쓴다.
  • 적용 배경: 추천 탭과 검색 탭, 장바구니, 외부 앱에서 모두 같은 상품 화면으로 들어가는데 각자 뷰컨트롤러를 만들어 push하고 있었다.
  • 적용 방식: 라우터 클래스가 상품 식별자만 받아 화면을 만들어 push하도록 하면, 상세 화면이 필요한 어디서든 식별자를 넣어 호출만 하면 된다.
  • 얻은 것: 컨트롤러마다 중복 코드가 생기지 않고 로직이 단순해지며 변경이 생겨도 한 곳만 고치면 일괄 적용된다.
  • 대조: 그런 계층이 없으면 화면을 여는 모든 뷰컨트롤러에 같은 생성과 push 코드가 반복해서 들어가야 한다.
왜 읽나같은 화면을 여러 진입점에서 열면서 생성과 push 코드가 사방에 복제돼 있다면, 전체 아키텍처를 갈아엎지 않고 라우터 계층만 떼어 쓰는 선택지를 볼 수 있다.
티몬
티몬 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 모바일·당근당근 테크블로그·

    웹뷰 다음의 레일을 깔다: 당근이 Lynx를 선택한 이유

    당근 프론트엔드코어팀이 WebView 기반 화면의 첫 프레임 렌더링 문제를 해결하기 위해 Lynx를 도입한 기록이다. 레퍼런스가 거의 없는 기술을 코드베이스 직접 분석으로 검증한 뒤 프로덕션에 적용했고, 1.9백만 사용자 A/B에서 Android 18%, iOS 37%의 첫 프레임 단축을 달성했다.

    요약 이어보기
    #cross-platform#webview#mobile-performance+2
  2. 모바일·토스 SLASH토스 SLASH·

    토스의 디바이스 팜 만들기

    토스가 각 팀이 각자 운영하던 작은 디바이스 팜을 하나의 중앙 플랫폼 '네뷸라(Nebula)'로 통합한 과정을 다룬다. Appium 대신 자체 드라이버를 개발해 클릭 13.5배, 텍스트 입력 10배의 성능을 달성했고, Android와 iOS 미러링도 직접 내재화해 실기기 원격 조작과 화면 실시간 공유를 동시에 가능하게 만들었다. 현재 100대를 넘어 수백 대를 향해 24시간 가동 중이다.

    요약 이어보기
    #android#ios#appium+2