ReactorKit はリアクティブかつ一方向のデータフローをサポートするための Framework です。ReactorKit について詳しく知りたい場合は以前の記事を参照してください。
ReactorKit はユーザアクションからのデータの流れや各クラスにおける強い制約が存在するため、ある程度の範囲はカバーできますが、副作用のある処理(ReactorKit の説明でいうところの side effect
) については制約がなく、公式では Service
レイヤーを設けてそこで処理するとの説明があります。そのためService
レイヤーで、より Testability や処理の見通しがいいような設計思想を Service
レイヤーで持つために、今回は Clean Architecture
を使おうということで、簡単に Clean Architecture
設計をまとめていきたいと思います。
Clean Architecture
メリット
Testability の向上
再利用性の向上
- 疎結合になることでそれぞれのクラスは特定のオブジェクトに依存しないのでクラス間の再利用性が向上し、実装の効率をあげることができる。
機能修正・置き換え
- 各レイヤーの責務が明確に分けられているので、DB の差し替えや UI の差し替えも比較的容易に行うことができ変更に強くなる。
デメリット
- 学習コスト
- 複数人で開発する際などは、チーム全体が
Clean Architecture
の設計思想を理解している必要がある。
- 複数人で開発する際などは、チーム全体が
- コード・ファイル量の増加
- がっつり新しい機能開発をする際は、それぞれのレイヤーを作る必要があるので、必然的にコード・ファイルの数は多くなる。
各レイヤの役割
下記の記事の図が大変分かりやすかったため参照させていただきます。
参照: https://qiita.com/koutalou/items/07a4f9cf51a2d13e4cdc
Presentation Layer
UI イベントの通知や表示などの処理をこのレイヤーで行い、ビジネスロジックなどはこのレイヤーでは持たない。
View
- 責務:
- ユーザから受け取ったタッチイベントなどのイベントを
Presenter
に通知 Presenter
から受け取った Model を元にView
を更新
- ユーザから受け取ったタッチイベントなどのイベントを
- 依存範囲:
- Presenter Protocol
- 責務:
Presenter
- 責務:
View
から受け取ったイベントを元にUseCase
を実行UseCase
から受け取った Model をView
に通知
- 依存範囲:
- UseCase Protocol
- 責務:
Domain Layer
iOS アプリケーションに依存しているビジネスロジックを担うレイヤー。
UseCase
Translater
- 責務:
UseCase
から通知とデータを受け取り Model を生成- Converter 的役割
UseCase
に Model を渡す
- 依存範囲:
- Model
- 責務:
Data Layer
通信とデータ管理のロジックを担うレイヤー。
Repository
- 責務:
UseCase
から通知を受け取り、DataStore
にデータの取得処理を依頼- どこからデータを取得するかは知る必要がなく、単にデータの CRUD に対応する I/F を記述する
UseCase
にデータを渡す
- 依存範囲:
- DataStore Protocol
- 責務:
DataStore
- 責務:
Repository
からの通知を受け取りデータを取得- サーバ・DBやキャッシュからの取得のハンドリング
- 必要なら DB の更新(Realm, CoreData など)
- 取得したデータを
Repository
に渡す
- 依存範囲:
- Entity
- Entity は Presentation Layer では使用されない
- Entity
- 責務:
ReactorKit + Clean Architecture での個人的な勘所
ReactorKit
の制約として、Clean Architecture
でいう Presentation Layer は、設計として担保されているので必要なさそうで、逆に Service
レイヤーとしての設計では、Domain Layer・Data Layer が必要そうです。ただし、Data Layer
以外のロジックをどこに持たせるかは悩ましいところで、処理の見通しの良さと Clean Architecture
の UseCase の役割を考えた場合は、Reactor の mutate()
にビジネスロジックは持たずに、UseCase
で処理を行った方が良さそうです。(Reactor にビジネスロジックを持たせたら、UseCase
の意味はなくなる + Reactor が複雑化する)
また、実際に取り入れたらコードを交えて記事を書きたいと思います🙃