MVC 정리
MVC패턴에서 사용자의 입력을 받게되는 부분은 Controller이다.
Controller는 사용자의 입력을 받으면 Model에 데이터를 요청하거나, 데이터를 변형하거나 작업을 한다.
이후 Model은 View를 업데이트한다.
View는 그리하여 Model과의 *의존성을 갖게된다.
View와 Controller역시 데이터를 주고 받는 때들이 있기 때문에 의존성이 생길 수 있다.
가장 큰 문제는 View와 Model의 의존성이 생기는 것!
*의존성: 서로 다른 객체 사이에 의존 관계가 있는것. 의존하는 객체가 수정되면 다른 객체도 영향을 줄 수 있다
iOS에선 사실 View와 Controller는 떼어놓기가 힘들다?
iOS의 viewController라는 클래스 파일에 예를 들어 화면에 버튼을 연결해서 버튼을 꾸미는 코드를 입력하기도 하는데, viewController에는 데이터를 가공하는 Controller의 코드, View를 Update하는 코드가 같이 들어가게된다.
클래스 이름부터가 viewController..
MVVM(Model - View - ViewModel)
1. 뷰(View) (화면을 그린다.)
- 화면에 표현되는 레이아웃 관여한다. UI에 관련된 것들을 다루므로 UI로직을 포함한다.
- 비즈니스 로직을 포함하지 말아야 한다.
- 각 컴포넌트에 대한 정보를 담고, ViewModel로 부터 데이터를 가져와 어떻게 배치할지등을 담고있다.
2. 뷰모델(ViewModel) (화면에 그릴 정보를 준비한다.)
ViewModel은 앱의 핵심적인 비즈니스 로직을 담고있는 코드 계층이다.
MVC패턴의 Controller와 비슷한 역할을 하고 있다.
View와 Model사이에서 View의 요청에 따라 로직을 실행하고, Model의 변화에 따라 View의 refresh한다.
Model에 변화가 생기면 View에게 notification을 보내주는 역할을 한다. View로부터 전달받는 요청을 해결할 비즈니스 로직들을 담고있다. ViewModel은 UI관련 코드로부터 완전히 분리되어있고, 따라서 ViewModel파일에는 SwiftUI와 같은 UI프레임워크를 import할 이유가 없다.
3. 모델 Model(데이터를 갖고있는다.)
실제 데이터를 저장한다.
RxSwift + MVVM의 핵심
* Command패턴 / Data Binding을 통한 View와 ViewModel의 의존성 제거.
Binding: View가 ViewModel을 관찰(Observing)하고있다. 그리고, 뷰는 관찰중인 대상의 값이 바뀌면 자신이 사용자에게 보여주고 있는 것들을 바꿔서 보여주게된다. 곧 ViewModel이 Observable이 된다. 그리고, View는 subscribe(구독)하게된다. 그러므로 ViewModel 내부에서 어떤 일이 일어나는지 View는 상관할일이 없다.
View가 ViewModel에 이벤트를 전달해주면 ViewModel은 Model의 데이터를 변경하거나 처리한다.
Model은 변경된 데이터를 ViewModel로 전달한다. ViewModel에 전달이 되서 ViewModel내부의 값이 바뀌면 View에선 Binding되어있던 요소들의 데이터가 바뀌게된다.그래서 View와 ViewModel의 의존성이 사라진다. 그리고, ViewModel과 Model도 의존성이 없거나 최소화된다.
이러한 형태로 만들기위해 ViewModel의 설계가 어렵다는 것이 단점으로 꼽힌다. 이런 Binding을 구현하기위해 클로저등 다양한 방법이 있을테지만 Rx와 Combine을 사용하면 보다 쉽게 구현할 수 있다.
MVVM의 기본 흐름
Entity -> Repository -> Model -> Service -> ViewModel -> View(ViewController)
또는?
Entity -> Usecase -> Data API -> Interactor(Repository) -> View Model -> View(ViewController)
Repository
- ViewModel은 일반적으로 Repository를 사용하여 데이터, 데이터베이스에 액세스한다. Repository는 앱의 데이터 소스를 추상화한 인터페이스를 제공한다.
- 뷰 모델은 데이터 소스에대한 구체적인 구현을 숨길 수 있다. 예를 들어서, 앱에서 데이터를 로컬디스크와 서버에서 가져와야 하는 경우 뷰 모델은 Repository인터페이스를 이용해 데이터를 가져올 수 있다.
- 실제로 데이터를 로컬디스크에서 가져오거나 서버에서 가져오는것은 Repository의 구체적 구현에 의해 처리된다.
- Repository의 결과물이 Entity이다.
Entity
- Actor가 필요로 하는 데이터 모델을 의미.
- 서버에서 받아온 원본 데이터. 즉, 가공되지 않은 데이터.
- Repository에 의해서 가져오게 된다.
Model
- Entity를 통해 앱에서 실제로 사용될 데이터로 가공하여 만들어진 데이터.
- 일반적으로 앱에서 사용되는 데이터 구조를 정의하는 구조체나 클래스로 구현된다. 예를들어 사용자 정보를 저장하는 User클래스가 있을 수 있다.
Service
- Repository를 사용해서 Entity(서버 모델)을 Model로 변환해준다. (Entity -> Model)
- 실제 로직을 처리한다.
ViewModel
- Service를 사용해서 화면에 보여줘야할 값의 형태(ViewMocel)로 변환한다. (Model -> ViewModel)
View
- ViewModel이 변경되면 화면에 세팅해주는 작업을 처리
결과적인 데이터의 흐름!!!!
View는 VIewModel을 바라보고있고, 값이 변경되면 데이터를 그린다.
ViewModel은 Service를 통해 Model의 비즈니스 로직을 처리하고 실제 View에 그려질 데이터를 갖고있다.
Service는 Model을 실제 뷰에 그려질 데이터로 업데이트한다.
Model은 Repository를 통해 데이터를 가져온다.
Repository는 Entity를 가져오고 Model에서 사용할 데이터로 변경한다.
Model(데이터)은 3가지 종류가 있다.
Entity ==> 원천데이터모델
Model ==> 서비스 로직에서 사용할 근본 데이터 모델
View Model ==> 근본 데이터가 화면에 보여지는 화면데이터모델
이러한 Model(데이터)를 처리할 로직을 담당하는
Service, Repository
처리한 Model(데이터를) 화면에 그리는
View