기존 성서알리미
ViewModel문제점
final class BoardDetailViewController: BaseViewController, BackButtonHandler {
private let viewModel: BoardDetailViewModelType
private let boardSeq: Int
private let categorySeq: Int
private let writeableAnonymous: Bool
private let writeableComment: Bool
init(categorySeq: Int, boardSeq: Int, writeableAnonymous: Bool, writeableComment: Bool, viewModel: BoardDetailViewModelType = BoardDetailViewModel()) {
self.viewModel = viewModel
self.boardSeq = boardSeq
self.categorySeq = categorySeq
self.writeableAnonymous = writeableAnonymous
self.writeableComment = writeableComment
super.init(nibName: nil, bundle: nil)
}
- 하나의 예시로 게시판 상세화면 코드를 보면은
MVVM
아키텍처를 채택함에도 해당 화면관련 상태값을 ViewController가 가지고 처리
- 익명으로 댓글을 작성할 수 있는지에 대한 상태값인
writeableAnonymous
가 단순 UI레이아웃을 구분짓는 용도임에도 ViewController
초기화함수에서 처리
위 문제 개선 코드
protocol BoardDetailViewModelType {
var categorySeq: Int { get }
var boardSeq: Int { get }
var writeableAnonymous: Bool { get }
var writeableComment: Bool { get }
}
viewModel.writeableAnonymous
viewModel.writeableComment
- 위처럼 게시판상세화면에 대한
ViewModel
에서 다음 상태값을 관리해줌으로써 ViewController
에서는 ViewModel
이 가지고있는 값을 사용만하고 ViewModel
내부에서 해당 상태값을 기존 내부 로직을 통해 갱신하여 사용
- 즉,
MVVM
아키텍처로써 ViewModel
이 가져야 할 의미를 명확히 할 수 있음
ViewModel Output관련 개선한 문제
private var cellModel: [BoardDetailCollectionViewCellModel] = []
private var boardModel: [BoardDetailHeaderViewModel] = []
Driver.combineLatest(
viewModel.boardInfoModel,
viewModel.boardCommentModel
)
.drive(with: self) { owner, result in
let (boardInfoModel, boardCommentModel) = result
owner.boardModel = boardInfoModel
owner.cellModel = boardCommentModel
owner.view.hideSkeleton()
owner.boardDetailCollectionView.reloadData()
}
.disposed(by: disposeBag)
- 기존 화면에 관련된 데이터바인딩코드를 작성할때 위 코드와 같이 프로퍼티에 데이터모델을 작성하고 viewModel의 Subject를 이용해 바인딩시켰음
- 허나
MVVM
아키텍처를 가짐에도 모델에 대한 데이터를 ViewController에서 가지고있다는 부분이 역할에 맞지않는다고 생각
protocol BoardDetailViewModelType {
var boardInfoModel: [BoardDetailHeaderViewModel] { get }
var boardCommentModel: [BoardDetailCollectionViewCellModel] { get }
}
viewModel.boardInfoModel
viewModel.boardCommentModel
- 기존
ViewController
의 UI모델 프로퍼티를 통해 값을 갱신하는것이 아니라 ViewModel
에서 관리하는 모델데이터만을 가져와 사용해줌으로써 기존 코드가 훨씬 깔끔해짐
MVVM
아키텍처에 맞게 오로지 ViewModel
에서 데이터를 관리하여 UI에 바인딩시키는 구조를 명확
- 또한
Subject
대신에 배열에 대한 프로퍼티로 변경해줌으로써 subscribe
하는 과정을 줄일 수 있었음