iOSをMVC,MVP,MVVM,清洁架构で実装してみた

何番煎じだよって感じですが,アーキテクチャに対する考チャに対する方は割と正解がなくて,自分の中に一つ落とし込んでおいて损はないと感じたため,补充という形で记事にさせていただきます。

アーキテクチャとは?

一言でいうと,

アプリケーションを绮丽丽装するための设计方法!

アーキテクチャを考虑しない设计でコードを书いていると以下のようなスにぶち当たります。

  • 一つのクラスの肥大化(iOSで言うところのFatViewController)
  • ロジックが烦雑になる
  • 同じ处理を使い回せない
  • チーム开発で役割分担しにくい
  • テストがしにくい
  • 属人化が进み,引き継ぎが难しくなる
  • 机能の追加,修正が困难
  • 等等…

正直まだまだあるとは思いますが,とにかく设计はこだわってないと后で地狱を见るということさえ伝わればOKです。

示例应用

アーキテクチャを语る上で叩き台にするアプリがいるなーと思ったので作りました。
阅覧するときは,见たいアーキテクチャのチャランチ(master / mvc / mvp / mvvm / clean-architecture / clearn-architecture + mvvm)に切り変えてください。

https://github.com/rockname/ArchitectureSampleWithFirebase

Firebaseでユーザーの登录/登录,投稿のCRUD处理をする,ものすごくシンプルなアプリです。

FatViewController

ブアーキテクチャのない世界をみなさんにはお见せしましょう。(ブランチはmasterです)

投稿一覧シーンであるListViewControllerを见てもらうとわかりますが,こんなに単纯なアプリにもかかわらずすでにコードが123行あります。

ViewControllerがすべての役割を担わされていることがわかりますね。
非常に胖な状态です。

役割

ViewController

  • UIのレイアウト
  • UIの更新
  • ユーザーのアクション通知
  • データの处理
  • データの更新通知
  • ビジネスロジック

评価

いいところ🙆‍

  • 思考停止でコーディングできる(これはいいところなのか…?)
  • UIKitの恩恵を最大に享受できる

悪いところ🙅‍

  • それ以外すべて

模型视图控制器(MVC)

Webアプリケーションフレームワークでよく闻くやつですね。

Appleの公式ドキュメントでもiOSアプリ开発はMVCが一般的みたいな书き方がされています。

https://developer.apple.com/jp/documentation/CocoaEncyclopedia.pdf

しかし,iOSのUIフレームワークであるUIKitはViewとControllerが密接に系がっており(ViewControllerというクラスがあるくらい),iOSのMVCはよくMassiveViewControllerだなんて皮肉を言われています。。

ではンプルアプリでは,ViewとControllerをひとまとめにしたViewControllerとModelの2层で设计しています。

からのように,Modelからの更新通知はDelegateパターンで受け取るようにしています。

役割

模型

  • データの处理
  • データの更新をViewControllerへ通知
  • ビジネスロジック
  • ViewControllerの状态の保持

ViewController

  • UIのレイアウト
  • 型号から通知を受け取りUIを更新
  • ユーザーのアクション通知
  • 型号の操作

评価

いいところ‍‍️🙆‍

  • なンプルな构成でわかりやすい
  • 模特のテストが可能に

悪いところ🙅‍

  • 查看と控制器が互いに密接に依存
  • 各型号で同じ处理を书くところが出てくる
  • まだまだViewControllerは脂肪

模型视图演示者(MVP)

https://zh.wikipedia.org/wiki/模型–视图–演示者

查看と模特の间にPresenterが挟まる感じのやつですね。

控制者とPresenterの违いの解釈は人それぞれですが,自分としては

  • 管理员:用户からイベントを受け取る
  • 主讲人:Viewからイベントを受け取る

というように考えてます。

サンプルアプリでは,模型,视图,Presenterの3层で设计しています。

役割

模型

  • データの处理
  • データの更新をPresenterへ通知

视图

  • UIのレイアウト
  • ユーザーのアクションをPresenerへ通知
  • UIの更新

主持人

  • 型号の操作
  • 型号から通知を受け取り查看を更新
  • 查看の状态を保持
  • ビジネスロジック

评価

いいところ🙆‍

  • まだまだシンプルでわかりやすい
  • が軽ーザーアクションの受け取りをUIKitから分离できたためViewControllerが軽量化
  • 机能の追加,更新がある程度やりやすい
  • 型号をFirebaseとの通信のみにしたためより抽象化できた

悪いところ🙅‍

  • 查看とPresenterの间で互いに依存关系が生まれてしまっている
  • Firebaseの处理が全体に蔓延しているためFirebaseに强く依存してしまっている

模型视图ViewModel(MVVM)

https://ja.wikipedia.org/wiki/Model_View_ViewModel

ViewModelの役割としてはPresenterと一绪なのですが,ViewとModelの仲介の仕方が违います。

  • 演讲者:ViewのUIとModelのDataの更新をその都度受けわたす
  • ViewModel:ViewのUIとModelのDataをDataBindingでつなげる

はンプルアプリの构成は以下の通りです。

図のように,RxSwiftを使用してDataBindingは実装しています。

また画面迁移もViewModel内で発火させたかったため,
Navigatorという画面迁移を扱うクラスを用意してそれをViewModelに持たせています。

役割

模型

  • データの处理
  • タをータを可观察的で包んで返す

视图

  • UIのレイアウト
  • へーーのアクションをViewModelへ输入
  • ViewModelの输出をUIへバインディング

视图模型

  • 型号とViewのバインディング
  • 查看の状态を保持
  • ビジネスロジック

评価

いいところ🙆‍

  • まだまだシンプルでわかりやすい
  • が軽ーザーアクションの受け取りをUIKitから分离できたためViewControllerが軽量化
  • 机能の追加,更新がある程度やりやすい
  • 型号をFirebaseとの通信のみにしたためより抽象化できた
  • ViewとViewModelの间での依存关系を一方向にできた

悪いところ🙅‍

  • Firebaseの处理が全体に蔓延しているためFirebaseに强く依存してしまっている
  • Rxの学习コストが高い

清洁建筑

https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html

さて,いきなりややこしい図が出てきましたね。

るの同心円状になっている4つの円は形状に一方向の依存关系を持つというルールを表しています。
MVPと比べたときに,各层の対応关系は以下のようになります。

  • 型号のデータ处理部分-> DB
  • 型号で扱うデータ型->实体
  • 查看-> UI
  • Presenterで扱うビジネスロジック->用例
  • Presenterで受け取るModelからの通知/ Viewの状态保持-> Presenters
  • Presenterで受け取るViewからの通知->控制器

sPresentersとControllersに分けるのは冗长すぎるため,
今回はViewControllerにその役割は委譲しています。

はンプルアプリの构成は以下の通りです。

Clean Architectureは依存关系に重きを置を设计であるため,各层はRxSwiftで一方向につなげています。

PostEntityを中心に置き,それをすべての层で使用します。
间违ってもFirebaseのフレームワークで扱うオブジェクトで扱うオブジェUI层で使ったりしてはいけません。

C,この场合UseCaseがRepositoryを持っているわけですが,あくまでも依存关系は
UseCase <-存储库
Use,UseCaseは扱う存储库がどんな実装であるかを知っていてはいけません。

これを実现するために,存储库の定义は协议to切って実装を见えないようにしています。
これにより,例えばRepositoryをFirebaseで実装していたけどサーバーをーを新しく立ててRESTApiを叩くようにしたくなったら,Repositoryの実装だけを変えることでそれは実现できます。

DBやUIの変更は割と继承に起きることですが,Clean Architectureではそれらを円の最も外侧に配置しているため,それより放置の実装は変えることなく最小限の修正で対応できる,というわけです!

役割

实体

  • データの型

用例

  • ビジネスロジック

资料库

  • データの处理
  • タをータを可观察的で包んで返す

视图

  • UIのレイアウト
  • ユーザアクションをUseCaseへ通知
  • 用例から流れてくるDataとViewのバインディング
  • 查看の状态を保持

评価

いいところ🙆‍

  • テストをかなりしやすい
  • 机能の追加,更新がかなりやりやすい
  • 依存关系が一方向であるため设计の手顺がわかりやすい(円の放置から実装すればいい!)
  • チーム开発での役割分担がかなり捗る

悪いところ🙅‍

  • 概念がわかりにくいためチーム全体で设计の指针をあらかじめ统一しておく必要がある
  • Rxの学习コストが高い

清洁架构+ MVVM

私は先のClean ArchitectureにMVVMを加えた形のアーキテクチャを采用しています。

変更点は查看の役割の中にある

  • 用例から流れてくるDataとViewのバインディング
  • 查看の状态を保持

にViewModelに切り离した感じです。

アCリケーションのロジックはUseCaseにもたせて,UIのロジックはViewModelに持たせるという考え方ができてかなりしっくりきてます。

まとめ

Fluxも书きたかったけど残念ながら时间切れ。。

个人的には,Clean Architecture + MVVMがオススメですー。
すぎてンプルアプリがシンプルすぎて,これUseCaseいらないんじゃない?となりそうですが,
ここに复数の存储库にまたがる处理が入ってきたりするとその恩恵をありありと享受できます。

また,ここおかしいんじゃないの?ってところはドシドシ教えてもらえると嬉しいです。

ありがとうございました。