Flux, Redux, SAMのデータフローをざっくり理解する

## 用語整理

### アーキテクチャ

設計思想、基本構造などを意味する、抽象的な概念。
抽象的な言葉なので、結構広い意味で使われる。
詳細な設計は含まれず、大枠の設計を意味する。
現在まで様々なノウハウが蓄積されており、それらがパターンとして一般的に利用されるようになっている。
すごく雑にいうと、説明する時に絵や図を描いて説明するようなものをイメージするとよさそう。

### フレームワーク

汎用的な機能をまとめて提供し、ソフトウェアの土台として機能するプログラム。「雛形」。
「アークテクチャ」より具象度が高い。
汎用的で再利用可能なコードをまとめたものであるという意味ではライブラリやモジュールに似ているが、フレームワークは全体を制御する役割を持つ。

#### アプリケーションフレームワーク

アプリケーションの開発をサポートするために設計されたフレームワーク。

- React(js)
- Anguglar(js)
- Vue(js)
- TEA(Elm)

#### 状態管理フレームワーク

データの流れを構造化するためのフレームワーク。
データの流れが複雑になって追えなくなるのを解消するために利用される。
これらの関心はデータの流れや状態管理にあるので、アプリケーションフレームワークがReactだろうがAnguglarだろうが思想は共通である。

- Flux
- Redux
- SAM(State-Action-Model)
- MVC（Model-View-Controller）
- MVVM（Model-View-ViewModel）

#### ビジネス用語としてのフレームワーク

一般にビジネス用語として使うフレームワークは、何かを手順化してまとめられた「型」「枠組み」のことを意味する。

- PDCA（思考プロセスフレームワーク）
- KPT（振り返りのフレームワーク）



## Flux

Storeがデータ管理の責務を持ち、Actionを発行することのみによってデータを更新する。その結果Viewが更新される。Dispatcherは、発行されたActionに対応するStoreが持つデータ更新ロジックを発火する役割を持つ。

![](https://i.imgur.com/Gy8vth3.jpg)

![](https://i.imgur.com/eJWXCEA.png)

### 構成要素

- **Store**
  アプリケーション内のデータ(Reactのstate)を持ち、次の状態にデータを更新するロジックも持つ。

- **View**
  表示部分。(ReactのComponent)

- **Action**
  ユーザー操作イベントやAPIレスポンスの受け取りなど、「何をする」という情報を持ったオブジェクト。

- **Dispatcher**
  アプリケーション内の全てのActionを受けて、Store内のデータ更新ロジックを発火する。

#### 参考サイト

[Fluxについての簡単なまとめ](https://qiita.com/yshimooka/items/c0305f4efa49dc020487)
[これから始めるReact.js 発展編 第1回 Fluxという設計思想](https://app.codegrid.net/entry/react-ex-1)



## Redux

Reducerが、Storeに送られてきたActionと現在のstateを元に次のstateを生成し更新する。その結果Viewが更新される。Actionはdispatch関数でStoreに送られ、それによってのみ状態が更新される。

![](https://i.imgur.com/oppcbeE.jpg)

![](https://i.imgur.com/vjcNwsv.png)

### 構成要素

- **Action**
  ユーザー操作イベントやAPIレスポンスの受け取りなど、「何をする」という情報を持ったオブジェクト。
  dispatch関数を使ってActionをstoreに送る。
  
- **Action creator**
  Actionを生成する関数。

- **Reducer**
  送られてきたActionと、元のstateをもとに、新しいstateを返す純粋関数。

- **Store**
  アプリケーションのstateを保持する。
  Actionがdispatch(送信)されるとReducerの呼び出しによってstateが更新される。

### Reduxの3原則

1. **Single source of truth**
  アプリケーション内でStoreは1つだけ。

2. **State is read-only**
  stateを直接変更することはできない。
  Actionをstoreへdispatch(送信)することでしかstateは変更できない。

3. **Mutations are written as pure functions**
   Reducer(stateを変更する関数)は純粋関数(同じ入力値を渡すたび、決まって同じ出力値が得られる関数)でなければならない。
   - 引数のstateを更新することはせず、新しいstateのオブジェクトを作成して返す。
   - 副作用を起こしてはいけない。例）APIコールやページ遷移
   - 非純粋関数を呼び出してはいけない。 例）Date.now() や Math.random()

#### 参考サイト
[Redux入門【ダイジェスト版】10分で理解するReduxの基礎](https://qiita.com/kitagawamac/items/49a1f03445b19cf407b7)
[React + Redux の基本的な使い方](https://kde.hateblo.jp/entry/2019/02/12/023325)



## SAM(State-Action-Model)

Fluxに似ているが、構成要素それぞれが担う責務が若干異なる。

![SAM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250456/56018b44-8c1a-1e7e-a199-dfcbd1ac1094.jpeg)

![SAM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250456/5c7a36da-2254-6e92-6789-e82b4cf52cc6.png)

### 構成要素

- **Model**
  Actionから受け取った計算結果をpresent関数でStoreに送り、現在の状態を更新する。
  状態が変化することでViewが更新される。
  現在の状態を保持する(FluxのStore)。
  永続化の責務も持つ。

- **Action**
  データを受け取り、そのデータをもとに状態計算をする関数。
  計算結果は、present関数を介してModelへ送りこまれる。
  ActionはView(ユーザー操作)とState(NAP ※後述)から発火される。

- **State**
  Modelから受け取ったデータを元にViewで必要となるデータに変換を行う関数。
  モデルの全てがViewに影響する訳ではなく、またViewの形がモデルと一致する訳でもないので、Stateを介して見通しを整える。
  現在のModelの状態を見て、次に発火する必要のあるActionを呼び出す。これをNAP（Next-Action-Predicate）という。（ex. Modelが持つtimeが0になった時、Modelの状態を見て自動的にTimeUp!と表示する）

#### 参考サイト

[SAMパターンの大雑把な理解](https://www.izumisy.work/entry/2017/10/14/184229)
[【SAM】ゲーマー諸君、コントローラを棄ててアクションを起こせ！MVCのCが消えて、Actionが残った理由 - ゲーム脳でもわかるMVC 本論](https://qiita.com/sasanquaneuf/items/2926555c9f4e7230b84f)



## FluxとReduxの違い
ReduxはFluxの派生なので、共通の特徴とそれぞれ特有の特徴がある。
Reduxの方が3原則があったりするのでややルールが厳しめな印象。

### 共通の特徴
- データの流れが一方向になり、複雑にならない。
- コードの設計がある程度決まっているため、どこになにを書くか、どんなふうに書くかが、全体的に統一された書き方となる。

### Flux特徴
- DispatcherがすべてのActionを受けつけ、各Actionに応じてStoreを更新する。

### Redux特徴
- Reducerが、Storeに送られてきたActionと現在のstateを元に次のstateを生成し更新する。
- Storeがシングルトン(必ず1つ)であり、SSOT的。
- Actionをstoreへdispatch(送信)することでしかstateは変更できない。
- Reducerが純粋関数になるので、関数の再利用性や単体テストのしやすさがある。