-
Notifications
You must be signed in to change notification settings - Fork 0
MVVM
![]()
만들고자하는 앱에 가장 적절한 아키텍쳐를 설계하는 일이 무엇보다 중요하다고 생각합니다. 앱의 주요 로직, 서비스의 크기 등의 요소를 고려하여 최적화된 디자인 패턴을 적용하는 것이 개발의 속도, 리팩터링 등에 영향을 미치기 때문입니다. 그렇기 때문에 거대한 서비스에나 적용할만한 Viper, RIBs 등과 같은 구조는 제외했습니다. 적절한 디자인 패턴을 적용한다는 것의 의미는 무조건 더 어렵고 깔끔한 구조를 선택하는 것이 아니라, 경제성을 생각하여 기능 구현 및 리팩터링에 최적화된 구조를 선택하는 것입니다. 앱의 기획부터 제작까지 모든 과정에 참여하면서 우리가 만들고자하는 서비스는 정해진 기능을 모두 구현하면 추가적으로 구현할만한 기능은 없을 가능성이 매우 높고, 서비스의 크기 또한 크지 않았기 때문에 너무 거대한 아키텍처는 위 그림과 같이 오히려 개발 속도의 저하를 초래할 수 있다고 생각했습니다.
그렇기 때문에 MV* 구조 중에 고민을 했고, 서비스의 크기를 고려했을 때 MVVM이 가장 적절하다고 생각했습니다. 물론 sceneCoordinator를 구현해서 화면전환 코드를 넘겼기 때문에 정확히는 MVVM-C 패턴을 적용하기로 했습니다. MVC패턴은 Viper나 RIBs와는 다른 이유로 후보에서 가장 먼저 제외했습니다. 바로 지나치게 작은 구조에 적절한 패턴이라는 이유때문입니다. MVC로 앱을 만들면서 느낀점은 view가 하나정도 있는 single view 앱정도에서나 간단하게 구현할만하다는 점이었습니다. viewController의 로직이 너무 무거워지기 때문에 앱이 조금만 커져도 코드의 가독성이 떨어지고 view와 로직을 하나의 객체가 관리하기 때문에 의존성이나 테스트에서도 문제가 생겼습니다. 결국 MVP와 MVVM을 고민했고 MVVM을 선택한 것에는 세 가지 이유가 있었습니다.
첫 번째는 모든 화면에 대응하는 presenter를 만드는 1:1구조보다, 상황에 따라 같은 데이터를 사용할 수 있는 1:N 관계가 필요했습니다. MVP패턴은 presenter가 화면을 그리는 것에 간섭을 하기 때문에 하나의 presenter가 다수의 view와 연결될 수가 없고 1:1구조를 유지해야만 합니다. 하지만 MVVM패턴은 viewModel이 화면 그리기에 개입하지 않고 데이터만 로직대로 처리하고 가지고 있기 때문에 해당 viewModel이 가지고 있는 데이터가 필요한 view들은 언제든지 접근하여 view를 그리는데 데이터를 활용할 수 있습니다.
두 번째는 RxSwift를 활용하기에 최적화된 형태이기 때문입니다. viewModel은 데이터를 가지고있고 view가 데이터에 따라 다르게 화면을 그린다는 것은 결국 view가 viewModel의 변화를 관찰(Observe)해야 한다는 것입니다. 이는 다시 말하면 Rx를 활용하기에 가장 적절한 구조라는 것을 의미합니다.
마지막으로 view와 viewModel의 관계가 단방향 수신으로 바뀐다는 점입니다. 이는 view와 로직을 조금 더 명확하게 분리하여 로직을 테스트하기 쉬워진다는 것을 의미합니다. 즉, MVP보다 MVVM이 view와 로직이 명확히 분리되는 구조라는 점에서 MVVM을 사용하기로 했습니다. sceneCoordinator 객체를 따로 생성한 이유도 마찬가지입니다. 화면을 presenting하는 역할마저 viewController에서 분리해내면 viewController는 뷰모델과 바인딩, input을 처리하는 일부 기능이외에는 다른 책임을 가지지 않는 상태가 될수 있다는 장점이 있습니다. 객체간의 역할이 명확해지고 테스트 가능 범위가 점점 늘어나는 것입니다.
결국 이 모든것은 경제성이라는 결론 때문입니다. 앱을 만드는 것에 있어서 정해진 개발자 수로, 특정 규모의 앱을 가장 빠른시간 내에 효율적으로 만들 수 있는 구조를 원했고 MVVM이 그에 가장 적절한 형태이기 때문에 MVVM패턴을 선택했습니다. view와 로직을 분리하는 일이 처음엔 시간이 더 걸릴지 몰라도 새로운 기능을 붙여나가는 데는 결국 훨씬 빨라지기 때문에 장기적 관점에서 더 적절하다고 판단했습니다. 만약 만들고자하는 서비스가 훨씬 더 거대했다면 Viper나 RIBs도 충분히 고려대상이었을 것입니다. 러닝커브가 높고 접근성이 어려워 초기에는 시간이 더 걸릴지몰라도, 결국 위에 제시한 그림처럼 어느 시점에서부터는 결국엔 더 빨라질 것이기 때문입니다.
created by 우송