Flutter Blocから始めるリアクティブプログラミング

僕はそもそもリアクティブプログラミングの概念やオペレーションの多さに圧倒されてあまり理解できず、自分に「そんなに流行ってないし、別に使えなくてもいいべ」と言い聞かせて理解できない自分を正当化していました。

しかし、最近このBloc(Buisiness logic component)パターンを知り、実践し理解することでその美しさに感動したので共有したく、この記事を書きました。

## Blocパターンのガイドライン

1. **インプットとアウトプットは、単純なStreamとSinkに限定する。(Inputs and outputs are simple Streams/Sinks only.)**
1. 依存性は、必ず注入可能でプラットフォームに依存しないものとする。(Dependencies must be injectable and platform agnostic.)
1. プラットフォームごとの条件分岐は、許可しない。(No platform branching allowed.)

flutterを使えば基本的には2,3は守られるはずで、今回主眼をおきたいのは1についてです。

## 従来のリアクティブプログラミングとは異なるアプローチ

Blocパターンは、リアクティブ・プログラミングのユニークな実装であり、従来のモデルとは一線を画しています。複雑さに圧倒されそうな他のリアクティブ・フレームワークとは異なり、Blocは明確な関心事の分離によって状態管理を単純化に成功しています。

単純化された結果の大事な概念はstreamとsinkとlistenという3つだけです。

僕のイメージは以下の画像です。

![bloc-stremとsink.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295481/367cd0a8-5f82-5f1b-dedd-329260a84e8e.jpeg)

これは基本型でBlocパターンではこの役割をそれぞれ何個にも増やすこともできます。

- streamの数を何本にもできる
- listenerがsinkすることもできる
- 同じstreamに対していくらでもlistnerを配置できる（broadcast時）
- 100個のstreamに対してsinkする
- etc

基本的に手続き型は1つのstream内で処理しているイメージすればかりやすいかと

## 例.gmailのアーカイブ機能

※ちなみに、実際の処理のフローは知らないので想像（Bloc的にやるなら）したものであり、説明のために少し動きを単純化しています

特に10000件とか溜まった時のアーカイブ処理をイメージしてください。
画面描画は一瞬で完了し、そのタイミングで画面を閉じようとすると処理中というアラートが出てくるという動作をします。
この動作から、以下のようなフローで処理が行われているのかなと想像しています。

![bloc-可視化.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295481/a0f9f3ef-090d-27f5-ec8f-617acbb8b437.jpeg)

ここで一番右端にあるviewStreamは、「このデータで描画しろよ！」と描画担当に渡すため用意したものです。（StreamBuilderに渡す）
このように、明確にロジック部分とview部分が区分されています。

## Blocの美しさ

Blocの本質は単純な実装だけで、ビジネスロジックをプレゼンテーションレイヤーから分離できることです、それによってUIがごちゃごちゃしたロジックから解放されるようにします。この分離はコードの可読性を高めるだけでなく、保守性も向上させます。

### ストリーム処理の可視化

また、データの流れを視覚化することもしやすいです。これは、イベントがどのように処理されてステートになるかを示すダイアグラムなどで示すことができます。このフローをマッピングすることで、開発者はアプリケーション内の状態管理を容易に理解し、デバッグすることができます。

### 手続き型プログラミングを超える利点

Blocを使って手続き型プログラミングからリアクティブ・プログラミングに切り替えると、いくつかの利点があります：

ドキュメンテーションの容易さ： Blocのストリーム・ベースのアプローチは、アプリケーションのフローをより簡単に文書化できます。正直streamの役割の詳細を書けば、パッと理解できます。これは、新しいチームメンバーへのオンボーディングや、アプリのアーキテクチャを明確に理解し続ける上で非常に貴重です。

マイクロサービスのような柔軟性： Blocのデザインはマイクロサービスと似ている部分があり、コンポーネントを簡単に交換、削除、追加することができます。この柔軟性により、摩擦を最小限に抑えながらアプリケーションの拡張や進化が容易になります。

簡素化されたテスト： Blocでは、個々のコンポーネントやイベントを分離してテストできるため、テストがより簡単になります。これは、より信頼性の高いコードと、よりスムーズな開発プロセスにつながります。

## webなどでなぜリアクティブ・プログラミングは普及しないのか？

その利点にもかかわらず、リアクティブ・プログラミングはすべての開発サークルで標準的なアプローチになっていないです。主なハードルは、以下の３つかと。

- 学習ハードルの高さ（体験談）
- 手続き型でなんでもできる
- *うまく使えないと副作用ばかり出てしまう*

## まとめ

- Blocパターンは美しい
    - リアクティブプログラミングをここまで単純化したgoogle *engineer* の方々は本当に尊敬
- とはいえ、特にリアクティブプログラミングは銀の弾丸ではないのであまり理解せずに使うと副作用だけがでやすいのも事実
- 美しさは主観なので、みなさんの美しいと思うやり方をしてください
- リアクティブプログラミングの入口としてpure flutter挑戦してみてはいかがでしょうか？

ReactiveXに見られるように、リアクティブ・プログラミングのコンセプトは以前からありましたが、この概念は初学者にはハードルが高いと感じました。しかし、Blocはリアクティブプログラミングを始めるのにちょうどいい。

データやステートの流れを視覚的に理解できるようにすることで、アプリ開発におけるドキュメンテーションという長年の課題にも対処しています。

BlocパターンはFlutterのステート管理を単純化するだけでなく、クリーンコードとアーキテクチャの原則を体現しています。ドキュメンテーションのしやすさからテストのしやすさまで、その利点は次のFlutterプロジェクトでリアクティブプログラミングを検討する説得力のある理由を提供しています。開発環境が進化するにつれて、Blocのようなパターンはより効率的でスケーラブルで保守性の高いアプリケーションを作りやすいと感じました。

reactive programinngへの興味が湧いた場合は一度flutterでbloc体験してみませんか？
※ その場合はライブラリなど何も入れずにやるのがおすすめです（体験談）

---

年初にアウトプットを増やそうと思い、進めたもののすぐ失速する悪い癖が出てしまったので今後は再度気を引き締めてまいりますので、機会があれば投稿した時見ていただければと。