Flutterやってみたよ part3 （アーキテクチャ調査編）

# はじめに
[前回](https://qiita.com/drafts/0227c4e209e8ce8d1032/edit)に引き続きFlutterアプリの製造を行っていきます。
今回はアーキテクチャを選択するためそれぞれのアーキテクチャについて調べようと思います。

# そもそも状態管理って？
初心者の方なら？状態管理って何？必要なの？となると思いますのでここはちゃんと理解しておこうと思います。ここを理解していないとたぶん適切なパターンを選べないです。

以下のmonoさんの記事がともわかりやすかったです。

[参考]

- [Flutter の Widget ツリーの裏側で起こっていること](https://medium.com/flutter-jp/dive-into-flutter-4add38741d07)


ざっくり要約するとは大まかに３つで成り立っていて

- Widget: ステートレス・immutable・軽量・設計図
- Element: ステートフル・mutable・WidgetとRenderObjectの仲介役
- RenderObject: ステートフル・mutable・レンダリングを担う

Widgetは状態を持っていないただの画面の部品で、RenderObjectがレンダリング（描写）を行います。
そこにElementがWidgetとRenderObjectに相互に状態を伝え画面の描画が実現されます。
これがツリー構造になっていて画面が出来上がります。

毎回全部の部品を作り直していたらコストパフォーマンス的に悪いので、特定のwidgetのみ状態によって再描画するように開発者は気をつける必要があります。誰でもサクサク動くアプリの方がいいですよね？単純な画面ならいいですが、実際に業務で作る画面とかは複雑な画面もあると思います。
そこで状態管理の手法がいくつか用意されているってことらしいです。

# 状態管理の方法って何があるの？
調べてみたところ[公式サイト（List of state management approaches）](https://flutter.dev/docs/development/data-and-backend/state-mgmt/options)では以下の６つについて書かれています。

- setState
- InheritedWidget & InheritedModel
- Provider & Scoped Model
- Redux
- BLoC / Rx
- MobX

などがあるそうです。
どれも素晴らしい記事があるので詳細は割愛してざっくり要約だけ書きます。


## setState
標準の機能ですね。
特段言及するところはありません。setState()を呼び出すことで状態の更新を行います。

```dart
    setState(() {
      aaa = 'bbb';
    });
```

## InheritedWidget & InheritedModel
標準で用意されているwidgetを駆使する手法です。

- 子孫が親の変更を感知できる
- buildメソッドを再度呼ぶことで再構築し直すことができる
- 先祖をO(1)で取得できる

やっぱり不必要なwidgetのビルドをコントロールしましょうねってことですね。
InheritedWidgetはBLoCでも使用されていますのできちんと理解しておくと良さそうです。

[参考]

- [InheritedWidget/InheritedModelとは何か]
(https://qiita.com/ko2ic/items/d7b744f19f213ef1e647)

## Provider & Scoped Model
ここからはライブラリを使用します。
ライブラリ：[scoped_model](https://pub.dev/packages/scoped_model)

基本的にはModelで囲むってだけでStatefullWidgetとStateを意識する必要がなくなるのでシンプルに感じます。小さめのアプリだったらこれで行けそう気がします。

[参考]

- [Scoped Modelの基本的な使い方（Flutter）](https://qiita.com/hayassh/items/690fa0d6528e056617b5)

## Redux
ライブラリ：[redux](https://pub.dev/packages/redux)、[flutter_redux](https://pub.dev/packages/flutter_redux) など

Javascriptのために考えられた設計で、仕組みは最もシンプルでわかりやすいと思います。
アプリ内の全状態のStore（json的なもの）があって、前の状態とアクションを組み合わせて新しい状態を生み出すという状態管理手法です。これによって**画面によって状態が異なる現象を防げる**のもいいですね。
そして**テストコードも書きやすい**とのことなので、これは結構使えそうな気がします。
まだ開発に慣れていない人とか品質を意識する必要がある時とかに向いている気がします。

[参考]

- [Flutterのアプリ設計(Redux)](https://itome.team/blog/2019/12/flutter-advent-calendar-day22/)


## BLoC
ライブラリ：[bloc](https://pub.dev/packages/bloc)、[flutter_bloc](https://pub.dev/packages/flutter_bloc)、[bloc_pattern](https://pub.dev/packages/bloc_pattern)、[hydrated_bloc](https://pub.dev/packages/hydrated_bloc)、[bloc_provider](https://pub.dev/packages/bloc_provider) など

Blocは最も多く導入されているであろう状態管理手法で、Googleも推奨しているとのこと。
Business Logic Componentの略で**ビジネスロジックとUIを明確に分ける**ことを目的としています。
BLoCの原則は以下の３つです。

- インプットとアウトプットは、単純なStreamとSinkに限定する。
- 依存性は、必ず注入可能でプラットフォームに依存しないものとする。
- プラットフォームごとの条件分岐は、許可しない。

上記を満たしていればあとはどんな作りでもOKとのこと。

Blocに保持しているデータをStreamとSinkを使って伝搬させることによって**非同期でwidgetを更新させる**ことができます。


[参考]

- [長めだけどたぶんわかりやすいBLoCパターンの解説](https://qiita.com/kabochapo/items/8738223894fb74f952d3)
- [FlutterのBLoCアーキテクチャを分かりやすく説明してみる](https://qiita.com/RyoShimizu/items/297e499cbb4fcd4e5af2)
- [Flutterの効率良い学び方]（https://medium.com/flutter-jp/flutter-learning-c5640c5f05b9）


## MobX
ライブラリ：[mobx](https://pub.dev/packages/mobx)と[flutter_mobx](https://pub.dev/packages/flutter_mobx)

MobXはReduxと同様にJavascriptのために考えられた設計で、Observables・Actions・Reactionsの３つで成り立っています。
アノテーションをつけることで３つの状態を関連付けています。javaっぽい書き方ですね。

[参考]

- [Flutterのアプリ設計(Mobx)](https://itome.team/blog/2019/12/flutter-advent-calendar-day23/)
- [MobX.dart](https://mobx.pub/)

# まとめ
全てのアーキテクチャについて調べてみましたが、個人的に気にいったのは**Redux**。テストのことも考えると良さげです。
もう一つはGoogleおすすめの**BLoC**。Rx使ってるのでやっぱりしっくりきます。

次回は[早速アーキテクチャ導入編]()として**Redux**と**BLoC**の導入サンプルを作りたいと思います！
ではまた👋

# 参考
大変勉強になりました。ありがとうございます🙇‍♂️

- [Flutter の Widget ツリーの裏側で起こっていること](https://medium.com/flutter-jp/dive-into-flutter-4add38741d07)
- [InheritedWidget/InheritedModelとは何か]
(https://qiita.com/ko2ic/items/d7b744f19f213ef1e647)
- [Flutterのアプリ設計(Redux)](https://itome.team/blog/2019/12/flutter-advent-calendar-day22/)
- [長めだけどたぶんわかりやすいBLoCパターンの解説](https://qiita.com/kabochapo/items/8738223894fb74f952d3)
- [FlutterのBLoCアーキテクチャを分かりやすく説明してみる](https://qiita.com/RyoShimizu/items/297e499cbb4fcd4e5af2)
- [Flutterの効率良い学び方](https://medium.com/flutter-jp/flutter-learning-c5640c5f05b9)
- [Flutterのアプリ設計(Mobx)](https://itome.team/blog/2019/12/flutter-advent-calendar-day23/)