今回はMVP, MVVM, Fluxについてです。
MVP
オブザーバー同期を使わずにフロー同期を使うため、ソースコードの流れを追いやすいのが特徴です。
個人的には一番理解しやすいので、このパターンが好きです。
iOSのアプリケーションにありがちなUIViewControllerのクラスが肥大化する問題を、Presenterと呼ばれるクラスを導入することで回避しつつ、テストも可能にします。
項目 | 説明 |
---|---|
Model | ビジネスロジック, BLE通信, データ |
View | UIに関係する処理, Actionの取得 |
Presenter | ModelとViewの橋渡し。 Actionを受けてModelを更新, Viewを更新する |
メリット
- データの流れが追いやすい
- ViewControllerからロジックを引き剥がせる
- テストしやすくなる
デメリット
- データの流れが冗長になりがち
所感
MVCと似ているので、一番とっつきやすいイメージ。
テストが導入しやすくなるので、ぜひ取り入れていきたいパターン
MVVM
Model, View, ViewModelから構成するパターン。
本は.Netで使われていたパターン
特徴はViewModelはModelの変更をデータバインディングで受け取る点。
NotificationCenterやRxSwiftなどのフレームワークを使うことが多い。
MVPとの違いは、PresenterがViewの参照を保持するのに対して、ViewModelはオブザーバー同期でViewを更新する。
(ViewModelがViewの参照を持たない)
項目 | 説明 |
---|---|
Model | UIに関係しない純粋なドメインロジック, データ, BLE通信 |
View | ユーザ操作の受付、画面表示を担当. ViewController |
ViewModel | Viewに表示するデータを保持. Viewからイベントを受け取り、Modelの処理を呼び出す |
メリット
- ViewとViewModelを切り離せる
- Modelを変更したらViewも自動的に更新される
デメリット
- RxSwiftなどを使う分、使い方を学ぶ初期コストが大きい
- 設計思想を知っていないとコードを追うのが困難
所感
RxSwiftを使う場合、フレームワークを使うことになるので、導入へのハードルが高い。
パターンを知っていない人に説明するのも大変なので、元から使っているプロジェクトでなければ導入することに躊躇する。
Flux
データの流れを単一方向にするパターン。
Action -> Dispatcher -> Store -> View
項目 | 説明 |
---|---|
Action | 実行するためのTypeと 処理に紐ずくデータを保持する |
Dispatcher | Actionを受け取り、Storeに伝える。 |
Store | 状態を保持し、Dispatcherから伝わったActionとdataに応じて状態を更新 |
View | Storeの状態を監視し、変更に応じて画面を更新する |
ViewからStoreに変更を伝える(ボタンが押されたなど)はDispatcherを経由して行う。
iOSで実現する場合は、enumを使ってActionを定義するとKeyを間違えたり、引数を柔軟に渡せるようになる
メリット
- データフローが単一なので、処理を追いやすい
- ViewやActionなど役割が明確なので、どこに実装するべきか迷いにくい
- Storeが状態を管理するのでViewControllerやViewから状態管理のコードを消せる
デメリット
- アプリの規模が大きくなってくるとActionが肥大化する
- かといって、小さいアプリに対してはオーバーな気がする(実装するための手順が多い)
所感
データの流れが単一になるのは魅力を感じる。
プロジェクトに導入する場合は、設計の指針をまとめた方が良いと思う。(入力制限や画面遷移をどのクラスで行うかなど)
まとめ
MVP, MVVM, Fluxについてまとめました。
実際にサンプルコードを作成することで、それぞれのパターンについてイメージを掴むことができました。
一番学んだことは、protocolなどを使って抽象化して、テスト可能にする点です。
UIのテストはできなくても、PresenterやActionを受け取った時の動作をテスト可能にすることで、その後の開発を迅速に進めることが可能になります。
そういった点で、もっと早くサンプルプログラムを作成して勉強しておけばよかったと思います。
次回はCleanArchitectureについてまとめます。
サンプルコード
サンプルコードはこちら。
0 件のコメント :
コメントを投稿