iOS - MVVM Pattern

이한솔·2023년 10월 5일
1

iOS 앱개발 🍏

목록 보기
20/49
post-thumbnail

MVVM

Model View ViewModel

Model: 앱에서 사용되는 Data와 그 데이터를 처리하는 Logic을 포함
View: 사용자에게 보여지는 화면(User Interface)을 구성
ViewModel: View에서 띄우고 싶은 정보만 Model에서 가져오고, View에서 사용자가 업데이트한 정보가 있다면 그것을 Model에 전달, View와 Model 중간 역할을 한다.

input을 View가 받고 그것을 ViewModel에서 핸들링하여 Model을 변경시키는 구조이며 Model이 변경되면 이것을 다시 ViewModel을 통해 View에 적용하는 구조이다.

어떠한 형태로든지 View 와 ViewModel은 연결되어야 한다는 얘기인데
결국 이것은 View 와 ViewModel은 연결을 위한 View와 ViewModel간의 의존성을 만들지 않으면서 연결을 유지할 수 있는 장치가 필요하다는 얘기가 된다.

앞서 View와 ViewModel을 연결할 인프라를 Binder 라는 개념으로 설명하고 있다. 다시 말해 Binder는 객체의 Property를 연결하는 Binding이라는 개념을 하위에 두고 View 자체에 내장하거나 혹은 독립된 어떤 위치에 있는 Binding객체를 이용해 View와 ViewModel 간의 property 수준의 연결을 하는 것이다.

View는 쉽게 말해 UI이고 UI는 수많은 하위 요소로 이루어져 있다.
이런 하위 요소들과 Model 핸들러(MVC의 Controller 혹은 MVP의 Presenter 등)와의 연결을 최상위 View객체가 특정 Model 핸들러 객체로 연결하거나 참조하는 것은 직접적으로 View 전체와 해당 Model 핸들러의 의존성을 만들어 내는 것과 같다.
따라서 View가 ViewModel의 형식을 인지하거나 특정 Model 핸들러 객체를 통째로 참조하는 것이 아니라 Binding을 통해 View의 각 하위 요소들에 대한 property 들의 연결만 유지한다는 얘기다.

그리고 이 Binding은 View에 소속되어 실제 ViewModel객체에 대한 정보를 숨기고 연결된 각 property를 ViewModel의 property와 동기화 시키게 된다.
여기서 동기화란 View의 Update, 혹은 Model의 Update를 의미하며
이를 특정 객체 참조와 개별적인 메서드 호출로 수행하는 것이 아니라
View와 ViewModel 의 연결된 property들의 변경 통보를 Binding 객체로 전달하여
one way 혹은 two way로 View와 ViewModel을 Update하는 방법을 말한다.

물론 실제로는 완전한 분리가 일어나지 않는다.
아이러니 하게도 MVP와 마찬가지로 View와 ViewModel 간의 의존성은 반드시 발생하며 (이 부분은 문맥(Context)에서 자세히 얘기해보겠다.)
ViewModel객체에 대한 참조는 무조건 View에서 가져갈 수밖에 없다.
다만 이 의존성은 View가 ViewModel에 대해 어떠한 형식도 담을 수 있도록 최상위 형태의 문맥(Context)으로 구성되며
(혹은 ViewModel을 연결할 수 있는 기능을 가진 특정 객체를 이용한다. 이하 문맥으로 지칭함.)
이 문맥을 기준으로 하위 property 들의 연결을 유지하고 ViewModel은 그 자체로 View에서 직접 노출되지 않는다.

따라서 직접 ViewModel을 View에서 획득, 조작할 수 없으므로 Binding에 의해서만 조작할 수 있으며
(상황에 따라서 문맥을 이용해 ViewModel을 획득할 수는 있으나 MVVM 패턴에서는 지양해야 한다.)
Binding 역시 특정 객체에 대한 의존성 없이 불특정 하게 연결된 ViewModel 객체의 property를 관리하는 수준으로 감추어져 있다.

말하자면 MVVM 패턴이 갖춰지려면 최소한 View 내부에서 ViewModel 객체의 특정 형식을 지정하거나 획득할 수 없어야 하고 ViewModel에서는 View를 포함한 View의 하위 객체를 획득할 수 없어야 한다.
(하지만 당연히 획득 하자면 할 수 있다. 하지만 이 역시 MVVM 패턴을 지키는 구조에서는 획득해서는 안 된다.)

즉, View에서는 특정 ViewModel의 형식이나 객체에 대한 정보를 알 수 없어야 하고 ViewModel에서는 View의 UI 객체들이나 UI 관련 속성들을 직접 건드릴 수 없어야 한다. (심지어 UI 관련 namespace까지 지정해서는 안 된다.)
실제 View와 ViewModel의 의존성이 발생하지만 이것은 타입을 특정하는 의존성은 아니며 사용자 입장에서 ViewModel이라는 불특정 객체를 아무렇게 할당하여도 Property만 정확히 일치 한다면 형식과는 무관하게 동일한 동작을 하는 Binding이 지원되어 코드 상으로 View와 ViewModel 과의 관계를 알 수 없게 하는 것이 MVVM 패턴의 구현 목표라고 보면 될 듯 하다.

그렇다면 ViewModel은 뭐라고 설명해야할까?
위에서 View와 ViewModel 사이의 관계에 대한 이야기를 하면서 이미 대충 밑그림을 그렸겠지만
ViewModel에 대한 개념을 따로 이야기한다면
ViewModel은 View의 추상화(abstraction)라는 것을 빼놓고 넘어갈 수는 없다. 그래서 이것이 View와 ViewModel이 서로 알 수 없다고 설명했던 핵심 근거가 된다.

요약하자면 ViewModel이 View를 추상화하기 때문에 View의 요소를ViewModel이 알수 없고
View 역시 ViewModel의 구체적인 형식에 관한 의존성을 가질 수 없게되는 것이라고 말할 수 있다.
(그렇기 때문에 View에는 어떤 ViewModel 형식을 주입(?)하더라도 문제가 생기지 않아야 한다. 의도한 정상동작을 하지 않을지언정...)

정리해보면, MVVM 패턴이라 함은
View와 Model 간의 분리가 되어야 하고 ViewModel 역시 View와 분리되어야 한다.
View와 Model 간 연결은 ViewModel을 통해서 이루어지므로 직접적인 분리가 가능해지며 View는 ViewModel에 대한 정보를 알 수 없고, ViewModel 역시 View 에 대한 정보를 알 수 없다.
당연히 View와 Model 은 아무런 관계를 맺을 수 없으며
ViewModel은 Model 객체를 보관하면서 Binding을 이용해 View를 Update하고 마찬가지로 View 역시 Binding 을 통해 ViewModel이 보관하고 있는 Model을 Update 하는 방식이라고 말할 수 있다.
뭐 이런 저런 설명이 지나치게 장황하고 어렵다면 이렇게 정리할 수 있을 것 같다. View와 Model의 분리, View와 ViewModel의 분리,
그러나 View의 Update를 위해 Binding으로 ViewModel을 연결하여 사용하는 것. 결국 이것으로 인해 작업 영역의 분리(디자인과 개발, UI와 로직) 을 구현하는 것.즉, 완전하지 않았던 기존의 MVC와 MVP의 목표를 구현하는 것.
이것이 MVVM 패턴이 추구하는 목표라 하겠다.

0개의 댓글