[iOS] Hot Chocolate MVC

GUNDY·2023년 11월 10일
2
post-thumbnail

MVC는 1979년 최초로 소개된 유서깊은 아키텍처로 여러가지 기본 패턴으로 구성된 높은 수준의 복합 패턴이다.

객체가 Model, View, Controller 중 하나의 역할을 수행하도록 한다.

하지만 이보다 더 유명한 명칭이 있었으니...

Massive View Controller!!

오늘은 MVC와 왜 Massive View Controller라는 애칭 멸칭으로 불리는지 알아보자

MVC의 역할과 관계

MVC에서는 Model, View, Controller의 세 가지 유형의 객체가 있다고 간주하고 그 경계를 넘어 서로 소통한다.

역할을 분리해서 얻을 수 있는 이점은 여러가지가 있지만 애플에서는 대표적으로 재사용성을 꼽는다.

프로그래밍에서 재사용성은 한번 작성한 코드를 별 수정없이 계속 재사용할 수 있음을 말한다. Swift에서는 상속이나 프로토콜 기본 구현 등을 통해 쉽게 코드 재사용을 할 수 있으니 Object-C에서 Swift로 넘어온 다음에도 MVC를 사용하는 것은 타당할 법도 하다.

데이터와 기본 동작, Model

A well-designed MVC application has all its important data encapsulated in model objects.

Concepts in Objective-C Programming - Model-View-Controller의 한 문장을 가져왔다.

잘 설계된 MVC 애플리케이션에는 모든 중요한 데이터가 모델 객체에 캡슐화되어 있습니다.

데이터가 애플리케이션에 로드되는 순간 모두 모델에 있어야 한다는 것이다.

???: 어 데이터 왔어? 저기 뒤로 가서 줄 서

주소록 등을 통해 사람의 정보를 저장한다면 생일 자체는 Model에 저장하더라도 그 날짜를 어떻게 표시할 것인지에 대한 방법은 Model에서 저장할 일이 아니라고 한다.

이런 선긋기 분리는 유연성의 여지가 있으나 UI적인 요소가 절대 배제되어야 한다.

사용자에게 정보 제공, View

The view should not be responsible for storing the data it is displaying.

뷰는 표시되는 데이터를 저장하는 일을 담당해서는 안 됩니다.

또 나온 선긋기.

물론 성능상의 이유로 캐싱등을 가질 수 있으나 기본적으로는 데이터를 저장하는 역할을 수행해서는 안 된다는 의미다.

ViewModel의 일부분을 표시할 수도, 전체를 표시할 수도 있다. 물론 여러 Model의 정보를 모두 표시하는 일을 담당할 수도 있다.

결국 ViewModel을 표시하기 때문에 Model이 변했는지 아닌지를 알아야 하는데...

Model은 특정 View에 연결되어서는 안 되기 때문에 변했는지를 알 방법이 필요하다.

Model과 View의 연결고리, Controller

A controller object acts as the intermediary between the application's view objects and its model objects.

컨트롤러 객체는 애플리케이션의 뷰 객체와 모델 객체 사이의 중개자 역할을 합니다.

  1. 일반적인 Cocoa MVC 디자인에서는 사용자가 View를 통해 값을 입력하거나 선택 사항을 표시하면 해당 값이나 선택 사항이 Controller에 전달된다.

  2. 그러면 ControllerModel에게 수행할 작업을 지시할 수 있다.

  3. Model은 특정 프로퍼티에서 변경된 값을 반영하고 Controller에게 보고한다.

  4. 변경에 따라 View를 업데이트 할 것을 요청한다.

결국 세 역할군은 이러한 모양으로 연결 된다.

Controller objects can be either reusable or nonreusable, depending on their general type.

한 가지 특이한 점은 재사용이 불가능 할 수도 있다고 표기한 것이다.

아무래도 Controller는 특정 ModelView를 연결해야 하니 단품이어도 상관없는 Model이나 View에 비하면 재사용성이 떨어질 수 밖에 없다.

그런데 이 중에 역할이 결합된 녀석들도 존재한다.

One can merge the MVC roles played by an object, making an object, for example, fulfill both the controller and view roles—in which case, it would be called a view controller.

바로 View Controller와 같은 녀석들이 그러하다.

View ControllerView를 소유하는데 View에 표시되는 데이터 관련 작업은 모두 이 View Controller에서 정의된다.

엥? 그러면 M-V-C가 아니라 M-VC 아냐?

이름은 같은 MVC지만 Model-View-Controller 보다는 Model-ViewController에 가깝다. 왜냐? ViewController의 역할을 모두 수행하는 ViewController가 있으니까!

그래서 View 역할군이 있지만 ViewController를 사용하는 Cocoa MVC 구조상 ViewController와 강하게 결합될 수 밖에 없다.

그래서 'Cocoa version of MVC as a compound design pattern'이라고 소개했던 원래의 그림과는 달리 아래의 모양새가 된다.

View를 애착인형마냥 착 끌어안고 있는 것.

View를 편애하는 Controller가 된다 이 말이야~

여기서는 또 하나의 문제가 발생하는데 View Controller(이하 VC)는 뷰의 역할도 컨트롤러의 역할도 하다보니 하는 일이 많아서 결국 VC에 작성되는 코드가 많아진다.

그래서 Massive View Controller라는 애칭 멸칭으로 불리는 것이다!

이것이 전통적인 방식의 MVC 패턴이었는데, 모델과 뷰의 재사용성을 높이고자 애플은 뷰와 모델 사이를 갈라놓고 컨트롤러를 통해서만 소통하는 모양으로 바꿨다.

그 결과 Model과 View의 재사용성 극대화를 꾀했으나, 뷰는 컨트롤러의 애착인형이기 때문에 과연 재사용성이 좋아졌는지는 의문이다.

물론 애플말고도 MVC의 재사용성을 극대화하고자 하는 아키텍쳐 패턴들이 개발됐는데 그것이 MVP와 MVVM이라고 할 수 있겠다.

하지만 모양새를 보면 MVP는 코코아식 MVC와 닮아있다.

혹시 쌍둥이?

그래서 실제로 iOS에서 적용되는 MVP는 다음과 같은 모양으로 적용된다.

뷰컨도 뷰로 퉁쳐버리는 것이다!

또한 iOS의 MVVM도 이와 닮아있는데

간단히 설명하자면 뷰모델과 뷰가 바인딩되어있어서 자동으로 UI 업데이트가 이루어지는 것이 다르다.

결국 Massive View Controller의 역할을 줄이고 View에만 집중할 수 있도록 하는 것이 개선 방안인 것이다.

마무리

분명 MVC는 장점이 많은 아키텍쳐이고, 재사용성이 좋으며, iOS에서는 이를 쉽게 구현할 수 있다.

MVPMVVM이 그러하듯 VC를 그냥 View로 보고 따로 Controller 객체를 만들어보면 어떨까? 하는 생각이 들었다.

언젠가 MVPMVVM도 본격적으로 다루는 포스팅이 나오길.

profile
개발자할건디?

0개의 댓글