iOS 앱 점검(ObjC)

iOS 아키텍처 패턴 - MVVM

night-Ohl 2019. 5. 20. 20:15
반응형

iOS 아키텍처 패턴 - MVVM

원문 출처 : https://medium.com/ios-os-x-development/ios-architecture-patterns-ecba4c38de52

 

MVVM (Model, View, ViewModel)

우선 기본적으로 MVC, MVP, MVVM와 같이 MV(X) 패턴들은 다음과 같이 3가지 요소로 나뉜다.

일반적인 카테고리 특징은 아래와 같고, 패턴에 따라 조금씩 차이를 보인다.

Models

- domain data 또는  데이터를 다루는 data access layer를 담당하는 카테고리.

- ‘Person’, ‘PersonDataProvider’를 떠올려 보아라.

Views

- presentation layer (GUI)를 담당하는 카테고리.

- iOS 환경에서 접두사 ‘UI’가 붙었던 모든 것을 떠올려 보라.

Controllor / Presenter / ViewModel

- Model 카테고리와 View 카테고리를 연결, 조정하는 카테고리.

- 일반적으로 뷰에서 수행된 사용자의 동작에 반응하여 모델을 변경하고, 모델의 변경 사항을 뷰로 업데이트함..


MVVM만의 특징

MV(X) 패턴들 중 가장 최신이며 가장 좋다.

 

기존 패턴들의 문제가 해결되었기를 바라며 도식도를 먼저 살펴보면, View와 Model은 익숙하겠지만 중간자 역할을 하는 ViewModel이 생소하다.

 

다음 요소들은 MVP랑 꽤나 유사하다.

- UIViewControllerView에서 다룬다.

- View와 Model 사이에 긴밀한 연관점이 없다. (독립성)

 

추가로 Supervising 버전의 MVP처럼 ‘바인딩’을 수행하는데, 여기서는 View와 Model 사이의 바인딩이 아니라 ViewViewModel 사이의 바인딩이다.

 

- iOS의 현실적인 면에서 ViewModel이 무엇일까? 이는 기본적으로 UIKit에 독립적으로 View와 state을 표현한다.

- ViewModel은 Model의 변화를 유발시키고 업데이트 된 Model을 가지고 스스로 업데이트 한다.

- View와 View Model 사이의 바인딩으로 인해 View도 이에 따라 업데이트 된다.


바인딩(Bining)

MVP 부분에서 간단하게 언급했지만 여기서 조금 더 다뤄보면, Binding은 OS X development box로부터 온다. iOS toolbox에는 바인딩이 없다. KVOnotifications 방식을 가지고는 있지만 이게 바인딩만큼 편리하진 않다.

 

그렇다고 binding을 직접 코딩해서 쓸 것도 아니므로.. 두 가지 방식이 있다.

- RZDataBining 혹은 SwiftBond와 같은 바인딩 라이브러리들을 기반으로한 KVO 중 하나를 사용.

- ReactiveCocoa, RxSwift, PromiseKit full scalefunctional reactive programming 괴물들을 사용하자.


Functional Reactive Programming

요즘 사실 ‘MVVM’을 들으면 ‘ReactiveCocoa’를 떠올리기도 하고 그 반대도 마찬가지이다. 그 이유는 간단한 바인딩으로도 MVVM을 구현할 수는 있지만 ReactiveCocoa는 MVVM의 대부분을 구현할 수 있게 한다. (그렇다고 Reactive Programming == MVVM은 아니다…-_-;;)

 

reactive framework에 관한 사실 한가지를 짚자면, 큰 힘에는 큰 책임이 따른다는 것이다. reactive를 사용하여 쉽게 구현할 수는 있지만, 뭔가가 잘못됐을 때 이것을 디버깅 하는 데에 엄청난 시간을 쏟게 될 것이다. 아래의 콜스택을 보면 이 말이 어느정도 이해가 갈 것이다.

Reactive's Call Stack

간단한 예제로 디버깅을 수행한 것임에도 콜스택이 장난아니다..!

이렇다면, 간단한 앱을 구현하고자 했을 때에는 FRF framwork나 KVO조차도 너무 과하다고 느껴질 것이다.

(그냥 간단한 걸 만들고자 하는데 이러한 패널티를 감안해야 한다니..?!)

 

대신에 우리는

  • View Model에게 showGreeting 메소드를 이용하여 업데이트하고,
  • greeingDidChange 콜백 함수를 위해 간단한 프로퍼티를 사용하도록 명시적으로 요청한다.

좋은 아키텍처의 3가지 관점

 

다시 feature 평가로 돌아와서,

- Distribution(역할 분배) : 사실 이런 작은 예제만으로는 명확하게 알 수는 없지만, MVVM의 View가 MVP의 View보다 더 많은 책임(역할)을 가진다.

  • MVP의 View는 모든 책임을 단지 Presenter로 넘길 뿐이며 스스로 상태를 업데이트 하지 않는다.
  • MVVM의 View는 binding을 설립함으로써 View Model 로부터 스스로 자신의 상태를 업데이트 하므로 책임 비중이 더 커졌다.

- Testability(각 요소 독립 테스트 가능성) : ViewModel은 View와 관련하여 아무것도 모른다. 이러한 독립성은 각 요소를 각각 테스트 하기 쉽게 만든다.

View 또한 아마 테스트 가능할 것이나, UIKit 의존성 때문에 건너뛰는 게 좋을 수도 있다.

 

- Easy of use : 예제에서는 코드 양이 MVP와 같았지만, View에서 발생하는 모든 이벤트를 Presenter로 넘기고, View를 manually하게 업데이트하는 실제 MVP 패턴의 앱과 비교한다면, binding을 사용하는 MVVM 패턴이 훨씬 코드 양이 줄어든다.

 

정리 : MVVM은 매우 매력적인 패턴이다. 앞에서 언급한 접근성의 이점과, binding 덕에 View를 업데이트 하는 추가적인 코드를 작성할 필요가 없다는 이점이 결합되면서도, testability는 여전히 매우 좋기 때문이다.
반응형