본문 바로가기

Design Pattern

[iOS] MVVM에 대해 알아보자 (Feat. MVC, MVP)

# MVC를 간단하게 짚고 넘어가자

 Comment
  • Model
    • 데이터와 관련된 코드를 담고 있다. (데이터를 담아두기 위한 구조체, 네트워크 로직, json파싱 코드 등)
  • View
    • 사용자에게 보여지는 UI를 말함
  • Controller
    • view와 model간의 상호작용(값변경)을 할 수 있게 Action을 받아서 전달해줌

# 동작방식

apple 문서 참고

  • 사용자 action이 Controller에게 전달됨
  • action을 확인하고 model을 업데이트함
  • controller는 업데이트한 model값을 나타내줄 view를 선택함
  • view는 Model을 이용해 화면에 나타냄

MVC의 문제점

  • 널리사용되고 있는패턴이라 단순하다.(장점)
  • View와 Model사이에 의존성이 생긴다. → 가독성 저하 및 유지보수 not good
  • View와 Model사이에서 값을 만들어내는걸 Controller가 소유하고 이전체적인 코드를 VC가 소유한다. 그렇다보니 VC가 책임과 역할을 다해버리는 상황이 발생해 코드가 길어지고, 가독성이 떨어진다.

# MVP도 간단히 짚고 넘어가자

  • MVC와 동일한데 Controller의 역할을 Presenter가 대신한다.
    • Presenter - View에서 요청한 정보로 Model을 가공하여 View에 전달한다.

동작방식(?)

위키백과

  • 사용자 action들은 view를 통해 들어온다.
  • view는 데이터를 presenter에게 요청함
  • presenter는 Model에 데이터 요청함
  • Model은 Presenter에서 요청받은 데이터를 응답함
  • presenter는 view에게 데이터응답한다.

장단점

  • view와 Model의 인스턴스를 가지고있어 View-Model에 의존성이 없다. 왜냐하먄 presenter에게만 데이터를 전달 받기때문에!!
  • 의존성은 해결됬지만 view-presenter와의 의존성이 높아진다.

# MVVM이란 ?

  • 디자인패턴인데 View와 Model 그리고 ViewModel로 구성된 디자인 패턴이다.

# MVVM은 왜 등장했는가 ?

  • 중재자(ViewModel)는 View에 대한 정보에 신경쓰지말고(의존성을 낮춤), 데이터 바인딩을 통해 구현한다.
    기존에 사용하는 UIKit은 VC가 거의 모든 역할을 한다. Controller가 View계층, Model계층을 모두 소유하고 있으며, Model의 notification도 View가 유저 상호 작용하는 전달하는 방식 모두 Delegation통해 VC가 떠맏고 있는것이다. VC가 주인공

일단 이렇게 모든 책임을 다떠안으면 코드가 길어질 수 밖에없다는 문제점이 발생한다.

의견: 역할 분리가 잘되어있어야 수정삭제에 용이하고 관리하기가 편한데 수정하는데 하나의 뷰컨을 다훑어봐야하는 일이 생길 수도 있을것같다. 아직 그런 번거로움은 제대로느껴본적은 없으나…코드가 많아지면???

그런데 MVVM에서는 view가 주인공이다

# MVVM 역할 및 책임

  • MV는 기존 역할이 동일하다
  • View를 변경하고 view입력을 ViewModel에 전달하는 역할만 한다. 이런 점만 사용해 ViewModel로 이동을 한다.
    • Model Input: view 입력을 받고 model을 업데이트 합니다.
    • Model Output: VC에 Model Output을 전달한다.
    • Formatting: VC에 표시할 Model데이터 형식을 전달합니다.
  • ViewModel의 책임은 ?
    • 앱의 핵심 비느지스 로직을 담고 있다. 컨트롤로와 비슷한역할인데 view에 요청에 따라 로직을 실행한다.
    • VC는 서비스를 호출하거나 Model을 조작하지않고 그 책임은 전적으로 ViewModel에 있따.

# MVVM은 어떤 방식으로 동작하는것인가 ?

  • 기존에 MVC패턴은 view에서 받은 이벤트들을 VC에서 처리하고 값까지 변경하여 view에 보여주는 식으로 동작했다. 하지만 MVVM은 view에서는 이벤트만 받고 받을 이벤트를 ViewModel에 전달을 한다. 그러면 ViewModel이 받은 이벤트를 가지고 값을 처리하고 그값을 view로 다시 뱉어내 업데이트를 한다
    실제로 viewModel의 출력값을 얻기위해 view에 이벤트를 Input으로 받고 Ouput으로 view에 binding을 해주어야하는데 이 방법이 크게 4가지 존재합니다.

동작방식

위키백과

  • 사용자의 action을 viewModel로 전달한다.
  • viewModel은 Model에게 데이터를 요청한다.
  • Model은 viewModel에게 요청받은 데이터를 응답한다.
  • viewModel은 응답받은 데이터를 가공해 방출한다.
  • 방출한값을 view화면에 나타낸다.

# Bind방법

  • KVO(key-Value-Observing)
    • key경로를 사용해 프로퍼티를 관찰하고 값이 변경될때마다 알림을 받는다.
  • FRP(Functional Reactive Programming)
    • Rxswift / Combine 둘다 FRP에 프레임워크 방식이다.
  • Delegate
    • 값이 변경될때 알림을 전달함
  • Boxing(?) 노티를 말하는건가 ??
    • 속성 관찰자를 사용해 관찰자에게 값이 변경됨을 알린다.
    • 간단한 앱의 경우 이로 충분하다

# MVC와 비교했을때 MVVM의 장점 ?

  • 복잡성 감소 - 기존에 MVC패턴은 뷰컨에서 많은 비즈니스 로직을 제거하여 간단한 뷰컨을 만들 수 있다.
  • 표현형 - view에 대한 비즈니스 로직을 더 잘설명하여 가독성이 올라간다.
  • 테스트 가능성 - ViewModel은 뷰컨보다 테스트하기가 쉽다. 왜냐하면 view구현에대해 걱정할 필요가없기때문에(?)

# Reference

iOS MVVM Tutorial: Refactoring from MVC
[디자인패턴] MVC, MVP, MVVM 비교