Youjin Lee.

[꾸물꿈] MVVM, Observable Pattern 도입 후기 - 1

[꾸물꿈] MVVM, Observable Pattern 도입 후기 - 1

Amazing New Blog

프로젝트 꾸물꿈

꾸물꿈은 IT 벤처 창업 동아리 SOPT 34기 iOS 파트로 활동하면서 참여한 앱잼(APPJAM) 프로젝트다. 기획 2명, 디자인 3명, 클라이언트(iOS) 4명, 서버 2명으로 진행했고, 내가 지금까지 참여한 프로젝트 중 가장 인원이 많았던(..!!!) 프로젝트였다. SOPT의 앱잼은 약 2주 간의 합숙을 진행한다. 즉... 2주 동안 밤새서 개발하고 먹고 자고 개발하고 먹고 자고만 한다는 뜻이다. 나는 6월 중순에 프로젝트 매칭을 시작으로 7월에 합숙을 진행했고, 이 회고를 합숙 후 약 4개월이 지난 지금에서야 작성하고 있다 ㅎㅎ 지금은 App Store에 릴리즈까지 진행된 상태고, 리팩토링을 준비하면서 관련 개념들을 학습하고 있다.

꾸물꿈 App Store 링크 꾸물꿈 iOS Github 레포지토리 링크 꾸물꿈 디스콰이엇 링크

내용이 길어질 것 같아서 여러 글로 나누어 작성해 볼 예정이다.

MVVM과 Observable Pattern에 대한 이야기를 꺼내기 전까지

꾸물꿈 프로젝트를 진행하기 전 프로젝트를 여러 번 진행해봤지만 MVVM 패턴을 도입해서 프로젝트를 진행했던 경험은 없었다. MVVM 패턴이라는 이름 자체에서 오는 진입장벽이 있기도 했고, 일단 MVC로 프로젝트를 완성한 후에 MVVM으로 프로젝트를 리팩토링 해야겠다고 마음만 먹다가 완성도 전에 프로젝트가 종료된 적이 많았기 때문이었는데 ... 그래서 이번 프로젝트에서는 무조건 MVVM을 도입해야겠다는 마음이 있었다.

그런데 프로젝트 전에 팀원들과 이야기하면서 왜 MVVM을 써야하는지 이유가 필요하다는 말이 나왔다. 사실 iOS 개발을 한 시간이 오래됐고 아직도 MVVM을 도입해본 경험이 없었던 나는 마음이 좀 조급했다. 1년 동안 iOS를 공부하면서 남들보다 뒤쳐지는 것 같다는 생각도 있었고 여러 아키텍쳐, 기술 스택들을 공부해서 빨리 적용해야 한다는 압박감도 있었던 것 같다 ㅎㅎ... MVVM이 MVC보다 무조건 낫다는 생각도 있었어서 왜 MVVM을 도입해야 하는지에 대한 생각은 해보지 않았다. 그냥 코드를 뚱땅뚱땅 치면 결과물이 나온다는 게 재밌었고 성능? 메모리? 이런 건 별로 생각하고 싶지도 않았다.

그런 나에게 꾸물꿈을 함께 진행한 iOS 팀원들은 이유 있는 코드에 대한 생각을 정말 많이 하게 해줬다. 사실 솝트 이전과 이후로 개발에 대한 시각이 완전 달라졌다고 생각하는데 그 중심에 우리 iOS 팀원들이 있는 것 같다. 이 글을 볼지는 모르겠지만 정말... 고맙다... 보고싶다... ㅠㅠ

MVVM과 Observable Pattern을 도입하기까지

프로젝트를 구성하는 요소를 Model과 View, ViewController로 역할을 나누어 작업을 처리하는 MVC 패턴은 Massive ViewController로 불리는 등 많은 문제를 가지고 있다. 규모가 작을 경우에는 별다른 문제가 되지 않지만 View와 기능이 늘어나고 로직이 복잡해질 경우 프로퍼티 선언과 오토레이아웃 설정, 네트워크 통신 등의 모든 로직을 ViewController에서 담당해야 하는데 이렇게 될 경우 한 ViewController의 코드가 1000줄을 넘어가는 경우가 왕왕 있다. 이 경우 나중에 ViewController에서 에러가 생겼을 때 디버깅을 하기에도 쉽지 않고 수행되는 특정 로직을 찾기에도 어렵다는 단점이 생긴다.

꾸물꿈 같은 경우 내가 맡은 부분은 약속 상세 화면이었는데, 한 화면 내에서 3개의 세그먼트 컨트롤과 UIPageController를 사용해 총 4개의 ViewController를 구현해야 했다. 거기에 한 세그먼트(=ViewController)마다 비즈니스 로직들이 많아서 MVC로 구현하게 되면 ViewController들도 큰 의존성을 가지게 될텐데, 한 ViewController마다 1000줄이 넘어가는 크기가 되면 정말 돌이킬 수 없을 것 같았다...

결론적으로 정리하자면 뷰 관련 프로퍼티 선언, 오토레이아웃, Delegate 관련 로직, 뷰 관련 로직, 네트워크 통신 및 바인딩을 ViewController 내에서 모두 처리하는 MVC 로직이 한 화면 내에 많은 리소스가 존재하는 우리 프로덕트에서 심각한 문제를 낳을 것이라고 판단했다.

그러면 View를 최대한 분리해서 Controller의 역할만 수행할 수 있도록 하면 되지 않을까?

라고 사실 나도 생각했다! 굳이 ViewModel까지 도입해서 복잡하게 할 필요가 있을까? 라는 생각도 들었다.

근데 이후에 iOS 팀원 중 한명이 ViewController의 책임은 화면에 표시되기 위한 책임만을 가진다는 이야기를 해주었다. ViewController의 책임에 대해서는 깊게 고민해본 적이 없었는데 이번 기회로 많이 고민해보게 됐다. ViewController가 관여해야 하는 부분은 View와 관련된 로직이라는 생각이 들었고, View를 구현하는 직접적인 프로퍼티 선언이나 오토레이아웃, Delegate와 같은 로직은 View 내에서 작업하기로 했다. 그렇다면 View와 직접적으로 관련 없는 부분(데이터 바인딩, 네트워크 통신 등)은 어떻게 처리해야 하는지에 대한 고민이 생겼다. 해당 로직들은 View에도, ViewController 내에도 위치할 수 없기 때문에 이러한 비즈니스 로직들은 ViewModel이 담당해야 한다는 생각이 들었고, 결론적으로 MVVM 패턴을 도입하게 됐다.

MVVM을 도입하기로 결정한 이상 데이터 바인딩에 대한 고민을 해보지 않을 수 없었다. 클로저 바인딩이나 Observable Pattern을 쓰지 않았을 때 데이터를 바인딩하는 부분이 ViewController에 필연적으로 존재할 수밖에 없다. MVVM 패턴을 선택한 이상 데이터 바인딩은 분리되어야 했다.

Rx를 도입한다는 선택지도 있었으나 프로젝트 시작부터 MVVM을 사용하는 것은 처음이었고, 2주 안에 프로덕트를 완성해야 했기 때문에 RxSwift의 러닝 커브를 생각했을 때 쉽게 도입할 수 없었다. 합숙 전에 회의도 여러 번 하고 생각도 여러 번 해봤지만 새로운 기술을 배우는 것보다는 메이커로서의 책임을 수행하는 것이 우선이라고 생각했다.

그래서 나에게 남은 선택지는 클로저 바인딩과 Observable Pattern 두 가지였다. 결론적으로는 Observable Pattern을 선택했는데 주된 이유는 객체 분리에 있었다. 클로저 바인딩은 didSet과 같이 데이터를 바인딩해주는 로직을 ViewModel 내에 선언해야 한다. 즉 해당 로직을 ViewModel이 알게 되는데 **Observable Pattern을 사용하면 해당 로직을 객체로 분리해 ViewModel이 로직을 알 필요가 없어진다. ** 부수적으로는 팀원들 중 RxSwift를 사용하는 경우가 있었기 때문에 추후 리팩토링을 생각하면 Rx를 도입해야 했다. RxSwift의 기본 원리를 배우기 전에 Observable Pattern에 대해 익혀놓으면 도움이 될거라고 생각하기도 했다 ㅎㅎ 결론적으로 Observable Pattern을 이용해서 데이터 바인딩을 진행했다.

마무리

이번 글에서는 MVVM과 Observable Pattern을 도입하게 된 과정과 후기를 간략하게 적어봤다. 조금 더 적어보려고 했는데 이렇게 적는 데에도 이렇게까지 시간이 오래 걸릴 줄 몰랐다 ... 다음 글에서는 Observable Pattern을 도입하고 있었던 어려움이나 구현 과정에 대해 공유해보려고 한다. 슬슬 기억이 사라지고 있었는데 이제라도 쓸 수 있어서 다행이다 ㅎㅎ 그럼 안냥

© 2025 Youjin Lee. All rights reserved.