続編を書きました!
続・ぼくのかんがえたさいきょうのReact+Redux+CleanArchitecture
前書き
- 最近話題のFluxにおいてモデルをどう扱うのかについて、自分もたまたま似た課題に取り組んでいたのでアウトプットしてみたものです。
- まだ検証段階なのであれこれコメントいただけると幸いです。
- タイトルは、、一度書いてみたかっただけです(照
発端
- 扱っているプロダクト(UI)のメンテナビリティ、エンハンサビリティが低い
- 業務ロジックとUI制御ロジックの分離がうまくできておらず、
ちょっとしたUI改善でも業務ロジックの考慮が必要な状況。
- 業務ロジックとUI制御ロジックの分離がうまくできておらず、
- SPAになりさらにUIのコードは複雑化してきている
- UIだから複雑なアーキテクチャは要らないなんて言わず、DDDを取り入れてみたらどうか
と言うことで、インフラストラクチャ層の分離がしっかりしている CleanArchitecture の採用を検討し始めました。
前提
- 現状は React + Redux + re-ducks 構成のJSUIプロダクト
- 主な外部要因は
- ユーザーの入力
- API
- Local Storage
- 移行コストはなるべく小さくしたい
検証
サンプル1.プロトタイプ
- 由来・特徴
- まずはre-ducks構成をそのままなんとなく CleanArchitecture に当てはめてみた
- モデルをそのままstoreで扱う
- 良いところ
- 現構成からほとんど変わらずに適用できる
- シンプルなCRUDアプリケーションに使えそう
- 悪いところ
- UseCase層から脇道が出ている
- reducerが仕事をしなそうな一方で、selectorの負担が大きい
- view依存の強い値はlocal stateで扱うことになるが、これがコンポーネントの複雑さを招く
→ 複雑なアプリケーションではいずれ「view用のstoreを作ろう」ってなっちゃいそう
≒ storeとviewの結びつきが強い
サンプル2.外のデモを検証
- 由来・特徴
-
React+ReduxのTODOリストアプリをCleanArchitectureで作ったリポジトリ
があったので図にしてみたもの
-
React+ReduxのTODOリストアプリをCleanArchitectureで作ったリポジトリ
- 良いところ
- プロトタイプの operator が usecase と service に分解され、ちゃんと円の中心を通る道筋になっている
- Presenter と Controller の位置付けもわかりやすい
- 悪いところ
- viewとstoreの関係がプロトタイプと同じ
サンプル3.ストアを外へ(さいきょう)
- 由来・特徴
- viewとstoreの結びつきが強いなら、一緒に外に出してしまえばいい
- storeにはmodelやview用の値などが保持される
- usecaseから外に出る線はRxJSのobserbableと相性が良いという記述があったが、妥協してReduxでまかなっている
- usecaseが自分の処理に応じたactionを発行し、storeは自分に必要なaction(≒イベント)をreducer経由で拾う形にすることで、依存を内側に向けている
- 良いところ
- storeが外に出たことで「viewの状態」という役割が明確になった
- 完全ではないが前の2つよりRedux(ライブラリ?)を外側に追い出せている
- React + Redux だけである程度 CleanArchitecture を再現できている
- 悪いところ
- ReduxをExternal層に追い出しきれていない(妥協)
- サンプル1,2より移行コストが大きい
- その他
- re-ducksのmodule構成が保てなく(曖昧に)なっている
改めて検証
CleanArchitectureの原点に立ち返ってみる
- フレームワーク独立。アーキテクチャは、機能満載のソフトウェアのライブラリが手に入ることには依存しない。これは、そういったフレームワークを道具として使うことを可能にし、システムをフレームワークの限定された制約に押し込めなければならないようなことにはさせない。
- テスト可能。ビジネスルールは、UI、データベース、ウェブサーバー、その他外部の要素なしにテストできる。
- UI独立。UIは、容易に変更できる。システムの残りの部分を変更する必要はない。たとえば、ウェブUIは、ビジネスルールの変更なしに、コンソールUIと置き換えられる。
- データベース独立。OracleあるいはSQL Serverを、Mongo, BigTable, CoucheDBあるいは他のものと交換することができる。ビジネスルールは、データベースに拘束されない。
- 外部機能独立。実際のところ、ビジネスルールは、単に外側についてなにも知らない。
上記をどこまで守れているかを表にしてみました。
1 | 2 | 3 | 4 | 5 | |
---|---|---|---|---|---|
サンプル1 | × | - | △ | - | △ |
サンプル2 | × | - | △ | - | △ |
サンプル3 | △ | - | ◯ | - | ◯ |
- 1に関してはサンプル1,2はDomain層がどっぷりReduxに浸かっているため×、
サンプル3はusecase-reducerの部分以外は外に出せているので△ - 3,5に関してはサンプル1,2のDomain層とExternal層の結びつきから△
- 2,4は差があまりなさそう
大分甘くつけてますが、比較するとサンプル3の優位性が出てるかなと言うところです。
まとめ
- React + Redux + re-ducks構成のアプリケーションに CleanArchitecture を採用検討する流れを紹介
- コスト面からの落とし所としてサンプル3をマイベストとした
- 仮実装しかしていないので、継続的に検証を続けます。
参考文献
- clean-architecture-demo
- クリーンアーキテクチャ翻訳
- 持続可能な開発を目指す ~ ドメイン・ユースケース駆動(クリーンアーキテクチャ) + 単方向に制限した処理 + FRP
- FluxにはModelがないのではないかと思った覚書
- クライアントサイドのモデルとは何か 前編 後編
- Reduxにドメイン層を導入する
(やっぱり文字にしてみると検討の甘いところや結論が一足飛びになっていて説得力がないとか浮き彫りになりますね)