RxSwift #4 — RxSwift 를 이용한 MVVM 패턴

Kanghoon
4 min readOct 22, 2018

이번에는 MVVM 패턴을 RxSwift 와 함께 사용하는 방법에 대해 알아보려고 합니다.

먼저, 우리가 흔히 사용하고 있는 MVC 패턴을 먼저 살펴보면서 시작해봅시다.

1. MVC 패턴 이란?

  • MVC : Model + View + Controller
RxSwift: Reactive Programming in Swift book
  • MVC 패턴은 대부분의 앱에서 쓰이는 간단한 패턴입니다.
  • Controller 는 가운데에서 ModelView 모두를 업데이트 시킬 수 있습니다. View 데이터들을 화면에 보여주는 역할만 하고, Model은 앱의 상태 지속을 위해 데이터를 읽고 씁니다.
  • MVC 는 단순한 앱에서는 간단 패턴일 수 있지만, 앱이 커져서 많은 클래스를 가지게 된다면 어떨까요? 일단 한 개의 Controller 에 더이상의 코드를 추가할 수 없는 것부터 시작됩니다.
  • 애플의 MVC 패턴은 ViewController가 강하게 연결되어 있어 ViewController 가 너무 많은 일을 합니다. 이 때문에 ViewController 의 코드는 몇천줄을 넘어가고, 오래전부터 MVC 패턴을 두고 “Massive View Controller Pattern” 이라는 말이 나오기 시작했습니다.
  • 다만, Class를 Overloading하는 것이 나쁜 습관인 것이지 이 자체가 MVC 패턴의 단점인 것은 절대 아니다. 이미 많은 앱들이 MVC 패턴으로 잘 개발되었기 때문입니다.

2. MVVM 패턴 이란?

  • MVVM : Model + View + ViewModel
RxSwift: Reactive Programming in Swift book
  • ViewModel 은 View를 표현하기 위해 만들어진 Model
  • ViewModel은 비즈니스 로직을 관리하고 센터 역할로 Model과 View 사이에서 통신합니다.

MVVM 패턴은 다음과 같은 규칙을 따릅니다.

  1. Model은 다른 클래스들이 데이터 변경에 대한 notification을 보내지만이들과 직접 통신하지 않습니다.
  2. ViewModel은 Model과 통신하며 데이터 ViewController(View)로 내보냅니다.
  3. ViewController는 View Life Cycle을 처리하고, 데이터를 UI 구성요소에 bind할 때만 View Model 및 View와 통신합니다.

Q : 그렇다면 ViewModel은 MVC에서의 ViewController가 하는 역할을 하는건가요?

A : 그렇기 하고, 그렇지 않기도 합니다.

문제는 ViewController 에 View 와 관련없는 코드를 작성하는 것입니다. 그렇게 코드를 작성하다 보면 결국 MVC 패턴에서의 Massive ViewController와 동일해집니다.

MVVM 패턴은 이 문제를 해결하기 위해 ViewController와 View를 묶어 단독으로 View를 컨트롤한다. (비즈니스 로직은 ViewModel로)

MVVM 패턴의 장점

  • MVVM 의 또 다른 장점은 코드 테스트가 용이하다는 점입니다. 비즈니스 로직으로부터 View의 생명주기를 분리하기 때문에, ViewController와 View 모두에 대해 명확하게 테스트 하는 것이 가능합니다.
  • ViewModel 은 UI 단에서 완전히 분리되어있고, 필요시에 재사용이 가능합니다. 즉, View를 대체하는 것만으로도 iOS, MacOs, tvOS 까지 마이그레이션 할 수 있습니다.

3. MVVM + RxSwift 예제

MVVM과 RxSwift를 같이 사용한 간단한 예제를 살펴봅시다.

Model.swift

ViewController.swift

  • ViewController 에는 UI를 그리고, ViewModel 의 데이터와 바인드시키고, 이벤트를 Input 으로 넘기는 코드만 작성합니다.

ViewModel.swift

  • Model에서 발생한 notification은 ViewModel의 init 에서 다룹니다.
  • ViewModel의 outpu t을 View가 구독합니다.
  • View에서 ViewModel의 input으로 명령으로 보내고, ViewModel은 명령을 받아 Model에 반영합니다.

--

--