View

300x250

TCA에 대한 공부를 시작하기 전에 MVVM에 대해 살펴보다가 아래의 아티클을 발견했다.

https://medium.com/@esung/mvc-정말제대로알고계신가요-875f1323f6c0

 

MVC, 정말제대로알고계신가요?

저는 꽤 최근까지 MVC라고 하면 모든 개발자가 같은 개념을 떠올린다고 생각했습니다. 애시당초 디자인패턴이나 아키텍처를 배우는 이유가 다른 개발자, 특히 다른 도메인의 개발자들과의 의사

medium.com

내가 알고있던 애플에서 사용하는 MVC는 사실은 전형적인 MVC와는 다른 구조라는 내용이였다. 또잉…? 이게 무슨 소리야?? 라고 생각하면서 글을 좀 살펴봤는데, 맞는 말을 던지고 있는 것 같았다.

그래서 요 충격을 받은 기회에, MVC를 간략하게 짚고 넘어가려고 찾아봤고, 이를 간단히 여기에도 글로 정리해두려고 한다.

요기 아래 링크의 Apple Developer Document Archieve 에서 MVC 패턴에 대한 내용을 확인할 수 있다.

https://developer.apple.com/library/archive/documentation/General/Conceptual/CocoaEncyclopedia/Model-View-Controller/Model-View-Controller.html#//apple_ref/doc/uid/TP40010810-CH14

다큐먼트에 따르면 아래의 첫 번째 그림이 전형적인 MVC를 나타낸 그림이고, 두 번째 그림이 애플에서 사용하는 코코아 MVC를 나타낸 그림이라고 한다. View와 Model 쪽에 연결 부분에서 차이가 있는 것을 볼 수 있다.

 

Standard MVC
Apple Cocoa MVC

 

 

Why?? 왜 구조를 바꿨지?? 에 대해서는 위 다큐먼트에 내용이 작성되어 있다. 쉽게 말하자면 View랑 Model은 재사용을 많이 해야하는 친구들이기 때문에 재사용성을 높일 필요가 있는데, 기존의 MVC는 View와 Model이 서로 참조를 하는 형태로 V-M 간의 의존성이 너무 높아 재사용하기 어려운 구조라고 한다. 이에 아예 View와 Model 사이의 참조 관계를 제거해서, View와 Model의 재사용성을 높인 것이 현재 애플의 MVC 버전이라고 한다.

여기에 관련해서 MVC와 함께 나오는 시리즈인 MVP, MVI, MVVM의 구조가 왜 그렇게 생겨먹었는지도 쫌쫌따리로 찾아봤다!


처음에 아무런 패턴이 없었던 시절에는 단순히 코드를 덩어리로 관리한다.

다만 이렇게 개발을 하자니 코드도 복잡해지고 생산성도 별로이니, 역할에 맞게 코드를 어느정도 분리하고자 한다. 이때 역할은 그래픽 영역, 로직 영역, 데이터 영역으로 주로 분리한다.

이러한 의도로 나온게 MVC 패턴이다. 그래픽-로직-데이터를 View-Controller-Model이 각각 나눠가진다.

 

이름처럼 Controller는 사용자의 입력을 받았을 때 View를 새로 그리도록 명령도 내리고, Model 에게 상태를 업데이트하도록 명령도 내린다. View는 Controller에 의해 새로 랜더링을 수행하면서 Model에게 필요한 상태값을 요청하기도한다. Model은 Controller에 의해 변경된 상태값을 View에게 알린다.

어떻게 보면 단순 코드 덩어리에서 모듈을 나눴다고는 하지만 완전히 분리가 되지는 못한 형태이다. 그냥 영역 구분만 한 느낌.

https://i.ytimg.com/vi/RS48MW-Dg2k/maxresdefault.jpg

 

앞서 언급한 것처럼, 각 모듈의 의존성을 떨어트려야 하는 이유는 주로 재사용성이다. 다른 모듈과의 의존성이 없으면 독립적인 존재이므로 다른 코드에서도 충분히 활용할 수 있는데, 의존성이 큰 경우에는 해당 코드를 덜어내기 어렵기 때문에 쉽사리 다른 곳에서 코드를 재사용하기 어렵다. 위 MVC 구조에서는 View와 Model이 서로를 알고있기 때문에, 둘이 함께 사용되는 경우에만 해당 코드를 재사용할 수 있다.

또, MVC 구조는 Controller가 사실 여러 View의 동작을 책임져야 한다.

여러 개의 View에 대해 관리하면서 Model의 상태 업데이트도 처리해야 하고, 유저의 입력도 처리해야하다보니 Controller의 크기가 매우 커지는 문제가 발생한다.

→ 보통 이 문제로 MVC를 버리고 MVVM이나 다른 아키텍처로 떠났던 것으로 기억한다.

그래서 등장한게 MVP 패턴이다.

MVP 패턴에서는 Presenter는 View를 하나만 책임진다. View에서 액션이 들어오면 Presenter는 이에 대응하는 로직을 처리하며 Model의 상태를 업데이트하고, 이 값을 받아와 뷰를 새로 그려준다.

이 형태가 내가 익히 들었던 Apple의 MVC 형태와 동일한 것 같다. 이전 Async Swift 에서 세션을 들으면서 만났던 MVP는 되게 어렵다고 느껴졌었는데, 이렇게 풀어서 보니 그냥 내가 알고있는 MVC 였다. 그때는 왜 이걸 이해하기 어려웠을까… 성장했나…? ㅋㅋ

MVP 에서는 Controller 대신에 Presenter를 사용하고, View와 Model 간의 의존성을 제거하면서 기존의 방식보다 View와 Model의 재사용성이 훨씬 좋아졌다. 또 controller보다 presenter의 크기가 훨씬 가벼워 복잡도가 낮아지는 이점이 있다.

그러나, 앱이 복잡해질수록 View와 Presenter의 결합이 강해지는 문제가 있다. (UIView와 UIViewController는 특히 이런 부분의 결합이 심하다. 요게 적절한 예시일지는 모르겠지만) 이에 따라, View와 Presenter의 양방향 결합을 최대한 줄여서 독립적인 모델로 만들어 재사용성과 테스트성을 높이고자 하는 니즈가 있었다.

요런 이유로 MVVM 구조가 제시되었다.

MVVM에서는 View는 스스로가 직접 자기 자신을 그린다. 화면을 그리기 위한 상태값은 ViewModel에서 가져오는데, 이 값을 ViewModel이 직접 View에게 전달하는 것이 아니라 View가 값을 가져가는 방식을 선택하여 ViewModel의 책임을 줄였다. 이 덕분에 ViewModel이 여러 View의 Model이 되더라도 단방향성 차조로 인해 ViewModel 자체는 View의 존재를 모르기 때문에 ViewModel을 독립적인 모듈로 만들 수 있었고, 이를 통해 재사용성을 높일 수 있다.

TCA를 공부하면서 봤듯이, 구조가 복잡해지면 복잡해질수록 오류가 발생하지 않는 안정적인 구조가 중요하며, 이를 위해 사람들이 꺼내든 카드가 단방향 순환 구조였다. 양방향으로 데이터를 주고 받다보면 어디에서 문제가 발생했는지 알기 어렵기 때문에 데이터의 순환 방향 자체를 고정시켜 버리는 방법을 선택한다.

이를 반영해 나온 구조가 MVI 구조이다.

MVI 구조에서는 사용자의 입력이 Intent로 전달되고, 이게 Model로 전달되어 상태가 업데이트되며, Model에서 화면을 그리기 위한 데이터를 View에게 전달한다. 이때 View에게 전달하는 데이터는 수정이 불가능한 immutable data로, 해당 화면을 새로 그리기 위해서는 다시 Intent → Model → View 의 방향으로 데이터를 넘겨줘야 한다.


흠… 흥미롭다. 내가 MVC라고 굳게 믿고있었던게 MVP 구조였고, 나는 아직도 MVP 구조가 “헷갈려, 알아야 하는데” 라고 생각만 하고 있었고, 정확하게 무엇인지는 모르고 있었다. 아직도 나한테는 MVVM 구조가 만능이라는 생각이 있긴 한데 ㅋㅋㅋ 조금씩 복잡한 구조를 설계하고 공부하다보면 왜 사람들이 단방향 순환 구조를 그렇게 갈망하는지 이해할 수 있게 되지 않을까 싶다. TCA 가보자구~

320x100
Share Link
reply
반응형
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31