iOS, Swift/ArchitecturePattern

Swift ) MVVM 탄생과정, 특징 - EEYatHo iOS

EEYatHo 2021. 7. 5. 17:01
반응형

MVVM을 제대로 이해하기 위해서는,

MVVM이 나오는 이유와 배경을 알아야한다고 생각한다.

 

MVVM은 디자인 패턴이다.

 

디자인 패턴은 어쩌다 나온 것인지를 알기 위해서는,

프로그래밍 패러다임의 변환을 살짝 핥아봐야한다.

 

1950년대, 어셈블리어와 함께, 순차적 프로그래밍이 나타났으며, ( 단순한 명령어들의 나열 )

1970년대, C와 Pascal을 필두로, 절차적(절차지향) 프로그래밍이 나타났고, ( if, for, 함수의 등장 )

1980년대 C++과 1990년대 Java를 통해, 객체지향 프로그래밍이 나타났다. ( 클래스, 객체의 등장 )

 

 

객체지향 프로그래밍은 40년이라는 오랜 세월 동안, 현재까지도 이어져 내려오고 있으며,

수 많은 선조 프로그래머들의 노력 덕분에

유지보수와 협업에 용이한 "코드들의 구조" 에 대한 노하우. 즉, 데이터가 쌓이게 되었다.

 

이 데이터들을 패턴화 한 것이, "디자인 패턴" 이다.

 

 

정말 수 많은 디자인 패턴이 존재하며,
( 옵저버, 팩토리, 싱글톤, 어뎁터 등등 )

그 중에서도

웹, 앱 같은 유저 인터페이스를 통한 '이벤트 기반 프로그래밍' 을 잘 할 수 있도록 고안된 것이

MVC, Apple's MVC, MVP, MVVM, VIPER, RIBs 등이다.

 

 


 

MVC -> Apple's MVC -> MVP -> MVVM 순으로, 그 한계를 극복하고자 발전한 형태이며,

간략하게 그 과정을 알아보겠다.

 


 

 

전통적인 MVC

MVC : 1979년 Trygve Reenskaug 에 의해 만들어졌으며, 사진에서 보다시피 View와 Model의 (완전 직빵)의존성이 존재한다.

 

 

Apple은,

자신들의 OS에서 돌아가는 SW를 만들기 위한 IDE(=Xcode)를 만들어야 했었기에,

유저 인터페이스 디자인 패턴들을 고려하게 되었고,

MVC 보며, 다음과 같은 두가지 이유로, 해당 디자인 패턴이 적합하지 않다고 생각한다.


1. View는 앱에서 모양과 느낌을 나타내는데,

일관성있는 앱의 느낌을 유저에게 전달하기 위해서는,
이 View들에게 높은 재사용성이 필요하다.

 

2. Model은 도메인 관련 데이터를 캡슐화하기 때문에,

( 그냥 네트워크 통신할 때 쓰는 Struct를 어렵게 말한거다. )
같은 형태의 데이터를 다른 곳에서 또 쓰는 경우가 많고,

그러므로 높은 재사용성이 필요하다.

 

 

따라서 View와 Model은 서로 떨어트려서 의존성을 없애고 높은 재사용성을 취한다.

그렇게해서 만들어진게 Apple's MVC (= MVC Cocoa )이다.

 

참고 : 애플문서

https://developer.apple.com/library/archive/documentation/General/Conceptual/CocoaEncyclopedia/Model-View-Controller/Model-View-Controller.html

 

 


Appls' MVC ( MVC Cocoa )

 

애플이 원하는 데로, View와 Model은 서로를 모르게 되었다.

 

하쥐만, 이를 사용하던 개발자들은 점점 큰 프로젝트, 대규모 협업을 겪으며

Controller가 너무나 많은 역할을 한다고 느꼈다.

 

레이아웃 코드들,

유저 입력 프로세싱,

비지니스 로직,

데이터 변환,

화면 전환,

생명주기,

콜백처리(델리게이트 등),

네트워크 통신...

 

Controller 혼자 몸집이 비약적으로 커지게 된다. (Massive View Controller)

 

이를 해결하기 위해, "Controller의 역할을 덜어주자!"고 만들어진게 MVP 이다.

 


 

MVP

 

2004년, 마틴 파울러에 의해 발표되었다.

 

ViewController를 View로 취급하고, Model은 그대로 나둔 뒤, 중계자 역할로 Presenter를 추가하였다.

 

VC는 꼭 VC에서 처리해야하는 것들 ( 생명주기, 화면 전환, 콜백처리 등 )만 처리하게 나두고,

나머지는 모두 Presenter로 위임하였다.

 

 

하지만, Presenter가 view를 업데이트 하는 방식에서,

Presenter가 weak로 View를 소유하고, View에 있는 요소에 직접 접근하여 업데이트한다.

( View를 업데이트 하는 소스가 Presenter에 대부분 속해있다는 뜻 )

따라서, View가 하는 역할이 거의 없다.

 

또한, Presenter와 View가 서로 소유한다는 것은 높은 의존성을 뜻하며,

이는 개선할 여지가 있다는 뜻이다.

 

 

이들을 개선한 것이 MVVM 이다.

 


MVVM

2005년, MVVM 켄 쿠퍼와 테드 피터스가 자신들의 블로그로 발표하였다. ( MVP 나온지 1년만에 zz; )

 

중계자를 Presenter -> ViewModel로 명명했다.

 

 

View를 업데이트하는 코드들은 View들이 가지고,

이 코드들을 트리거하기 위해 Data Binding으로 ViewModel과 연결한다.

 

이를 통한 가장 큰 차이점은 뷰 로직과 비지니스 로직이 분리되었다는 것.

( Presenter는 마치, Model이라는 퍼즐조각을 View라는 판에 맞추는 것 까지 했다면,

ViewModel은 퍼즐조각들을 View에게 넘겨주기만 하고, 맞추는건 View 니가 알아서해~ 느낌 )

 

때문에 테스트 코드를 작성 할 때도, UITest와 UnitTest로 분리할 수 있다.

( View 로 UITest, ViewModel 로 UnitTest )

 

프로토콜과 함수들로 덕지덕지 하는 것도 bind로 끝내버려서,

View와 ViewModel 사이의 의존성도 낮아졌고, 중개자의 코드양이 MVP 보다 줄었다.

 

하지만 비동기 프로그래밍은 역시나 디버그가 어렵고, 성능부하도 많다는 단점이 있다.

 

또한, 규모가 커질수록 ViewModel이 비대해지는 경향은 아직도 남아있다.


개인적인 견해로는 MVVM은 애매한 위치에 있다고 생각한다.

 

 

혼자 개인 프로젝트를 진행하면, 대충 아무렇게나 MVC로 짜고,

 

직장에서 협업을 진행하는 경우, VIPER나 RIBs 처럼 더 확실하고 명확한 역할분리를 하는 것이 좋다고 생각한다.

 

MVVM은 명확한 가이드라인이 없기 때문.

어디에 넣을지 애매한 코드가 있을 때, 세분화가 많이 된 상태일수록 해결하기 쉽다.

SOLID 의 단일 책임 원칙과도 어느정도 결이 맞는 생각