본문 바로가기
Dev/고민과 삽질의 기록들🤔

아키텍처를 결정하기까지의 고민 (MVC, MVVM, Clean Architecture

by Mintta 2023. 9. 18.

MVVM 을 하게되는 이유

  • MVC, MVVM, Clean-Architecture

1. MVC로 시작된 프로젝트, 그 이유

최근 동아리 활동을 하면서 진행했던 프로젝트를 MVC로 진행했습니다.

사실 iOS개발을 시작하면 누구나 바로 접하는 아키텍처이기도 하고 여러 단점들(특히 Massive View Controller)로 한번 사용하면 다시 사용하지 않게 되는 아키텍처 중 하나임도 사실입니다.

 

하지만 그럼에도 이번 프로젝트에 MVC를 적용했던 데는 이유가 있었습니다.

‘규모가 작은 프로젝트에서의 MVC가 무조건 나쁜 것일까’라는 것이 고민의 시작점이였습니다.

 

디자인 패턴등과 아키텍처에 관해서 공부를 할 때 보았던 말 중에 “불필요한 변경, 혹은 과한 추상화는 오히려 독이다”라는 말이 있었습니다.

 

따라서 프로젝트의 요구사항을 분석해보았을 때 우선 데이터 바인딩이 필요한 뷰가 거의 존재하지 않았고 UI Component들을 잘 공용화해서 사용한다면 Massive View Controller를 만들지 않을 것 이라는 확신도 있었습니다.

2. Unit Test관점에서의 MVC의 문제점

그렇게 MVC로 프로젝트를 마무리했습니다.

 

하지만 MVC로 했을 때의 문제점의 시작은 다름 아닌 Unit Test의 적용을 고민하기 시작한 시점부터 여실히 드러나기 시작했습니다.

현재 Unit test를 적용한 상태는 아니지만 Unit test를 적용해야겠다라는 니즈가 생긴부터 현재 설계를 test관점으로 바라봐야만 했습니다.

test관점으로 봤을 때 MVC의 ViewController는 testable한 것인가 ?

 

그에 대한 답은 “NO”입니다.

 

우선 Unit Test로 우리가 결국 하고자 하는 것, Unit test를 하고자하는 목적을 먼저 생각해본다면

 

우리의 로직이 특정 input이 들어왔을 때 우리가 의도한 Output을 내는가?

그리고 unit이라는 단어의 뜻만 봐도 알 수 있듯이 단일 요소를 뜻합니다.

Unit, 단일이 key point입니다.

 

즉, 단일 로직이 우리가 의도한 대로 정상적으로 잘 동작하는가 ?

를 테스트하고자 하는 겁니다.

 

만약 이때 단일 로직이 아닌, 복수의 다중 로직이라면 의도한 결과값을 얻지 못했을 때 그 원인을 특정지을 수 있을까요 ?

물론 후보는 찾을 수 있겠지만(이것도 쉬운 과정은 아닐 수도 있겠지요) 결국 문제점을 찾기 위해서는 추가 테스트가 필요하거나 계속 오리무중 상태일 겁니다.

 

이런 상황이 MVC패턴에서 곧잘 생깁니다.

Apple플랫폼에서의 ViewController는 하는 일이 너무 많습니다.

  • Model을 가지고 User event에 따라 model을 변경하는 로직
  • View를 그리는 로직
  • View에 대한 로직

loadView시점을 이용해서 View를 따로 분리한다고 해도 import UIKit을 하고 있는 이상 땔래야 땔 수 없는 Life cycle등과 같은 로직도 존재합니다.

 

결국 ViewController가 맡고 있는 수많은 책임은 다중 로직에 해당하고 Unit test를 통해서 얻고자 하는 목성을 달성하기 어렵다는 말이 됩니다.

후보1: MVVM ?

MVVM은 어떨까 ?

 

MVVM의 경우 뷰를 제외한 Model에 관한 로직을 완전히 뷰로부터 독립시킬 수 있습니다.

ViewModel이 그 책임을 완전히 가져가는 것이죠.

뷰로부터 완전히 독립되었기에 import UIKit 같은 불필요한 import도 필요없습니다.

ViewModel은 오직 Model을 바꾸는 로직에만 집중합니다.

 

이렇게 되면 책임이 완전히 분리됩니다.

ViewModelUI와 전혀 상관없는 객체로 유지되기에 unit test를 하기에 안성맞춤인 구조가 되는 것입니다.

 

사실상 ViewModel이 testable하게 되어 test가 원활하게 이루어진다면 거의 반이상은 이기고 들어가는 것과 다름 없습니다. 앱의 비즈니스 로직이 ViewModel에 존재할텐데 ViewModel이 요구사항에 맞게 돌아간다면 코어 기능은 우리가 생각한대로 움직이고 있다는 뜻일테니 말입니다.

 

또한 새로운 프로젝트의 경우 ‘일기 느낌’이 나는 프로젝트이기에 데이터 바인딩이 생길 요소가 많다고 판단했습니다.

후보2: Clean Architecture ?

조금 더 복잡하고 더욱 더 세밀한 책임 분리를 할 수 있는 Clean Architecture의 경우도 한번 알아보겠습니다.

 

Clean Architecture에 대한 설명자체는 아래 링크로 대체하겠습니다.

https://codingmon.tistory.com/40

 

Clean Architecture는 결론부터 말하면 조금 과하다는 생각이 듭니다.

 

Clean Architecture를 통해서 분리된 레이어에 맞게 설계를 하다보면 정말 각 레이어가 자신의 역할을 분명히하고 명확히 구분되어있고, 각자의 책임을 다하는 객체들이 협력하는 공동체느낌이 납니다.

 

하지만 그에 따른 트레이드 오프로 너무나 많은 보일러코드와 코드점핑이 존재합니다.

정말 버튼 하나를 눌렀을 때 일어나는 간단한 interaction도 Clean Architecture에 따라 구현하게 된다면 약 5개의 파일(VC, ViewModel, UseCase, Repository, Service)등을 추가로 생성해야하고 그에 따른 로직도 필요하며 각각의 객체의 결합도를 낮추기 위한 프로토콜까지 들어갑니다.

 

모든 팀원들이 Clean Architecture의 대한 이해가 있지 않는 한, 오히려 팀원간의 병목현상을 불러일으킬 것이라고 생각했습니다.

결론: MVVM

그래서 결론.

책임을 UI와 완전히 분리하여 응집도를 높여 Unit test를 하기에도 적합하고 데이터 바인딩을 하기에도 용이한 MVVM을 새로운 프로젝트의 아키텍처로 채택하기로 했습니다.


새로운 프로젝트의 아키텍처를 결정하게 된 의사흐름을 정리했습니다. 정말 생각이 떠오르는대로 글로 남겼기에 두서 없는 글이 될 수 있을 것 같습니다.

 

고려하지 못한 부분이나 생각치 못한 부분도 정말 많을 것 같네요.. 뭔가 부족함을 느끼게 된다면 그건 제가 더 성장할 수 있는 부분을 찾은 거니까 오히려 좋은 거겠죠?

댓글