FluxとClean Architectureについて比較して考えてみた

## はじめに

- CyberAgentのインターンで触れたアーキテクチャである、Flux, Clean Architectureについての個人的な見解を述べるだけです
- 「アーキテクチャはこうあるべき」みたいな原理主義的な話はしません

## この記事で書くこと

- Fluxの特徴
- Clean Architectureの特徴
- MVVM × Clean Architecture

## Fluxの特徴

FluxはFacebook社が作成したアーキテクチャパターンで、もともとはJSで使われていたものです。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3137363138302f34636133343163322d613661302d346132372d386461352d3962313165393337396662372e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640264/a7f299c9-0845-a251-0e3e-7189064a1c8e.png)

各要素の役割として以下の通りです。

- `Dispatcher`: 発火されたActionをStoreに通知するもの
- `Action`: Viewなどから発火されたEventをDispatcherに通知するもの
- `Store`: Dispatcher経由できたActionに応じて、データを管理するもの
- `View`: StoreのデータをUIに反映させるもの、ユーザー操作に応じてActionを発火するもの

### メリット

- データの流れが単一方向であること
- DispatcherやActionがシングルトンで表される

### デメリット

- 規模が大きくなると、Actionが肥大化する
- Recycler Viewなど動的にリストビューを作成する処理をActionに書かなければならないため、関心の分離を満たせない場合がある？
- ビジネスロジックのみを完全に分離できない
    - KMM(Kotlin Multiplatform Mobile)等への対応が難しい
    - CyberAgentでもKMMへの対応

### MVCとの違い

よく比較されるアーキテクチャとして、MVC(Model View Controller)があります。Model, View, Controllerの役割としては以下の通りです。

- `Model`:  システムの中でビジネスロジックを担当する
- `View`: データ表示や入出力の処理をする
- `Controller`: ユーザーの入力に基づき、ModelとViewを制御する

しかし、MVCには規模が大きくなるにつれ、ViewとModelの依存関係が複雑になる問題点があります。例えば、A画面ですでに生成されたModelを参照しながら、A画面内でもう一度同じModelを参照したい場合もあるかもしれません。そういった場合の依存関係は複雑になります。規模が大きくなればなるほど、この問題は顕著になります。

以下の画像がわかりやすかったので参考までに載せておきます。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f313736363930342f31306639333438642d326333622d383838322d613438382d3233323563616661666661342e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640264/6cc2293f-4737-004d-3609-282097a95fd3.png)


## Clean Architectureの特徴

Clean Architectureはレイヤードアーキテクチャ（責務のまとまりを**レイヤー**とし、それらを組み合わせて構成されるアーキテクチャ）の一つです。以下の画像で表されることが多いです。

![CleanArchitecture.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640264/57167a44-1c67-99cc-6ef5-052c81c4eeac.jpeg)


ですが、この図は個人的にとてもわかりづらいのでAndroidアプリを作成する際によく採用される、**MVVM×Clean Architecture**の図を作ってみました。このアーキテクチャはClean ArchitectureにMVVM（特にViewModel）を組み込んだアーキテクチャです。

```plantuml
@startuml app_architecture_class_diagram
package "Ui Layer" {
    package "View" {
        object Composable
    }

    package "Ui Logics" {
        class ViewModel
    }

    package "Ui Models" {
        class UiModel
    }
}

package "Application Layer" {
    class UseCaseImpl
    interface UseCase
}

package "Domain Layer" {
    class DomainObject
    interface Repository
}

package "Data Layer" {
    class DataSource
    class RepositoryImpl
}

' UI Layer Relations
Composable <.. ViewModel
ViewModel o- UiModel

' Application Layer Relations
ViewModel <.. UseCase
UseCase <|.. UseCaseImpl

' Domain/Data Layer Relations
UseCaseImpl <.. Repository
Repository <|.. RepositoryImpl
RepositoryImpl o- DataSource
RepositoryImpl -- DomainObject

@enduml
```


各レイヤーの役割としては以下の通りです。

- `プレゼンテーションレイヤー`: UIなどユーザーにどう見せたいか制御する責務を持ちます（上の図ではUIレイヤーとしています）
- `アプリケーションレイヤー`: ドメインレイヤーの抽象化された振る舞いを具象化し、アプリケーションで使用しやすい形に変換する責務を持ちます。
- `ドメインレイヤー`: データレイヤーで取得したデータをドメインに変換する責務を持ちます
- `データレイヤー`: 上位のレイヤーで使用するデータやライブラリを扱う責務を持ちます

### メリット

- 機能改善がしやすくなる
    - 関心の分離の原則により、関心事がしっかりと分かれているので機能改善・追加がしやすい
- テストがやりやすくなる
    - はじめにEntitiesだけをテスト→UseCaseだけをテスト→Presentation層のテストみたいな感じに、テストを細かい粒度で行えるようになる

### デメリット

- 実装コストが高い
    - 書くコード量はMVCの1.5倍くらい？
    - →早く実装しなければならないチーム・プロジェクトには向かないかも？

## まとめ

CyberAgentのインターンで触れたFlux、Clean Architectureについてまとめてみました。

今回自分なりに言語化してまとめてみたことで、それぞれのアーキテクチャへの理解が深まった気がします。また、それぞれ特徴があり「こっちの方が絶対に良い」のようなことはないということを感じました。

今後もこのような記事を投稿し、多くのアーキテクチャに関して比較・検証をしていきたいと思います 💪

## 参考にさせていただいたサイト

- [https://qiita.com/juchilian/items/d732afab315e3c7e8ba3](https://qiita.com/juchilian/items/d732afab315e3c7e8ba3)
- [https://qiita.com/kondo97/items/b1d7031f89334912fe97](https://qiita.com/kondo97/items/b1d7031f89334912fe97)