【iOS】MVVM에 대해서

기사를 이동했습니다.



htps : // 천. v / d_sho / rc c s / e c6545 a d371137
앞으로는 위의 기사에서 업데이트하겠습니다. (2021/10/03)

MVVM에 대해 처음부터 여러가지 조사해 나름대로 있어야 할 모습이
정해져 왔기 때문에 기사로서 정리합니다.
RxSwift의 요소는 가능한 한 배제하여 순전히 MVVM에 대한 고찰을 정리했습니다.
※단, 실장에는 RxSwift의 이용을 전제로 하고 있습니다.

전제



이 기사에서는 다음 사고 방식으로 이야기를 진행합니다.
  • 비즈니스 로직은 Model에서 구현됩니다
  • 데이터 바인딩은 RxSwift를 사용합니다
  • 가능한 한 1 클래스 1 의무로 한다

  • 1. 소개
    MVVM에 관한 기사를 보고 있으면 비즈니스 로직을 ViewModel로 구현하는지, Model로 구현할까
    2 패턴으로 나뉩니다. ViewModel에서 상태를 관리하기 때문에 비즈니스 로직도 ViewModel
    에서 구현하는 것이 알기 쉽다는 의견은 잘 알지만 ViewModel의 원래 역할을 생각하면
    Model에서 구현하는 것이 좋다고 생각했습니다.

    2. 소개
    많은 경우에 RxSwift를 채용하고 있는 것에 따라 RxSwift를 채용합니다.
     RxSwift 편리! !

    3. 소개
    재이용성을 생각하면 1클래스 1책무가 되는 것이 이상적이라고 생각하고 있습니다.

    MVVM의 구성 요소



    모델


  • 비즈니스 로직 (통신 처리 및 DB 작업 등)
  • 데이터 형식 정의

  • 보기



    ViewModel 데이터를 데이터 바인딩으로 자동으로 그립니다.

    ViewModel


  • View와 Model 간의 전달
  • View에 대한 상태 유지

  • MVVM 처리 흐름



    아래 그림과 같은 이미지입니다.



    상단의 왼쪽에서 오른쪽으로의 처리는
    View는 ViewModel을 참조하고 ViewModel은 Model을 참조하여 진행합니다.
    하단의 오른쪽에서 왼쪽으로의 처리는
    Model에서 ViewModel에 알리고 ViewModel에서 View에 알리는 것으로 진행합니다.
    (어째서 ViewModel→View의 경우만을 가리키고 DataBinding라고 말할 것이다.)

    ViewModel의 구성 요소



    ViewModel의 역할이나 어떻게 구현할지 매우 고민했습니다만, 알면서 현재 상태 이하와 같이 자신 속에서 정리하고 있습니다.



    여러분은 어떻게 ViewModel을 구현하는가?
    부디 코멘트 부탁드립니다!

    검색바에 입력한 문자열로 GitHub의 리포지토리를 검색해 일람표시하는 샘플을 만들어 보았습니다.
    ViewModel은 이런 식으로 구현했습니다.

    ViewModel.swift
    
    import Foundation
    import RxSwift
    import RxCocoa
    
    final class RepositoryViewModel {
    
        struct Input {
            // 監視対象(トリガー)
            var repositoryName: Observable<String>
        }
    
        struct Output {
            var rx_repositories: Driver<[RepositoryInfo]>
        }
    
        // MARK: - Properties
    
        // Viewから受け取るトリガー
        private var _input: RepositoryViewModel.Input!
        // Viewにデータをバインドする
        private var _output: RepositoryViewModel.Output!
        // GitHub APIからデータを取得するModel
        private let repositoryModel = RepositoryModel()
    
        // 初期化
        init(trigger: RepositoryViewModel.Input) {
            _input = trigger
            _output = RepositoryViewModel
                .Output.init(rx_repositories: createOutput())
        }
    
        func output() -> RepositoryViewModel.Output {
            return _output
        }
    }
    
    extension RepositoryViewModel {
    
        // InputからModel経由でOutputを生成する
        private func createOutput() -> Driver<[RepositoryInfo]> {
    
            return repositoryModel.rx_get(from: _input.repositoryName)
        }
    }
    
    

    프로젝트에서 M-V-VM의 참조 관계



    전제의 3. 「가능한 한 1 클래스 1 책무로 한다」를 생각하면 이하와 같은 관계가 좋은 것이 아닐까 생각합니다.



    View : ViewModel = 1 : 1 (간접적으로 1 : n 은 있을 수 있다)
    ViewModel : Model = 1 : 1
    Model : Model = n : n

    요약



    여기 2, 3일에 조사한 것을 기초로 생각한 것을 정리해 보았습니다.
    아직 부족한 곳은 있지만, 거기는 수시로 갱신해 갑니다.
    코드도 준비되면 링크 붙이기 때문에 좋으면 봐주세요.

    아직도 불충분한 부분도 있다고 생각하므로, 지적해 주시면 매우 도움이 됩니다.

    이상입니다.

    좋은 웹페이지 즐겨찾기