개발을 시작하는 이야기

MVVM(Model, View, ViewModel) 패턴 본문

개발 이야기/Swift

MVVM(Model, View, ViewModel) 패턴

Teiresias 2022. 3. 25. 18:24

MVVM 패턴 또한 MVC와 마찬가지로 애플리케이션에 주로 사용되는 디자인 패턴이다. 이름에서 알 수 있듯이 Controller를 대신하여 ViewModel을 갖고 있는데, ViewModel 또한 Controller처럼 View와 Model의 중계자 역할을 수행한다.

 

MVC 관련 글은 여기

MVVM 모델

Model

  • 데이터, 비즈니스 로직, 서비스 클라이언트 등으로 구성
  • 실질적 데이터

View

  • UI와 관련된 객체들로, 사용자에게 보이는 화면
  • 유저 인터랙션을 받는 역할을 한다.
  • iOS에선 ViewController까지가 View의 역할이라 할 수 있음.

ViewModel

ViewModel은 MVVM 패턴에서 핵심적인 비즈니스 로직을 담고 있는 코드의 계층이다. MVC 패턴의 Controller와 비슷한 역할을 하고 있다. View와 Model 사이에서 View의 요청에 따라 로직을 수행하고, Model의 변화에 따라 View를 그린다.

 

Model에 변화가 생기면 이를 View에 notification을 보내주는 역할을 한다. 또한, View로부터 전달받은 요청을 해결할 비즈니스 로직을 담고 있다. ViewModel은 UI와 관련된 코드들로부터 완전히 분리되어 있고, 따라서 ViewModel 파일에는 UI프레임 워크를 import 할 이유조차 없다.


iOS가 MVC 에서 MVVM으로 넘어가는 추세라고 한다. 기존에 사용하던 UIKit은 MVC 패턴을 기반으로 만들어졌지만, 비교적 최근에 나온 SwiftUI가 MVVM 패턴을 기반으로 하기 때문이다. 이론상으론 MVC의 Controller와 MVVM의 ViewModel이 하는 역할이 크게 다르지 않아 보이지만, UIKit에서는 ViewController가 주인공이고, SwiftUI에서는 View가 주인공이라고 할 수 있다.

 

UIKit의 MVC에서는 Controller가 거의 모든 역할을 수행하고 있다. ViewController단위로 하나의 화면이 구성되고, 일반적으로 Controller는 View와 Model을 모두 소유하며 View의 유저 상호 작용을 전달하는 방식도, Model의 Notification도 모두 Delegation 방식으로 ViewController가 떠맡고 있다.

 

하지만, SwiftUI의 MVVM에서는 View가 ViewModel을, ViewModel이 Model을 소유하는 방식이다. Controller 단위로 화면이 구성되는 것이 아닌, View가 화면을 주도하며 필요한 ViewModel을 가져와 사용하는 구조이다. 따라서 ViewModel은 View에 대해서 알고 있을 필요가 없기 때문에 코드가 단순해질 수 있다.

 

이렇게 적어두고 보니 MVVM의 장점만 부각되지만 완벽한 디자인 패턴은 아니다. 간단한 UI에서는 오히려 ViewModel을 설계하는데 어려움이 있을 수 있고, 데이터 바인딩을 필수적으로 요구하며, 복잡해지게 되면 Controller처럼 ViewModel이 빠르게 비대해지게 되는 문제가 생기게 된다. 하지만 iOS 개발에 있어 MVC와 MVVM의 구조적인 차이가 있고, SwiftUI를 반응형으로 설계한 만큼 MVC보다는 MVVM을 채택해 구조적인 이득을 챙겨 오기 위한 것으로 보인다.


SeSACFriend와 JHeritage에서 MVVM을 구현하긴 했으나 UIKit을 활용한 MVVM으로 제작했기 때문에 완벽한 효율을 내지는 못했을지도 모르겠다. 조만간 SwiftUI를 적용한 MVVM 패턴으로 간단한 프로젝트를 해봐야겠다.

 

참고 : 블로그

'개발 이야기 > Swift' 카테고리의 다른 글

UserDefaults  (0) 2022.03.27
Data Binding (Observable)  (0) 2022.03.26
MVC(Model, View, Controller) 패턴  (0) 2022.03.24
XIB를 활용하기  (0) 2022.03.23
StoryBoard를 사용하기  (0) 2022.03.22