Clean Architecture と React を組み合わせる
Clean Architecture と React を組み合わせるデモアプリが eduardomoroni/react-clean-architecture というリポジトリにあったので、コードを覗いたら勉強になった。
Clean Architecture を大づかみに理解する
よく出てくる図。
私の理解している限りでは、 Clean Architecture において重要なのはモジュールの依存関係に規律を導入することで、中でも「重要なビジネスルール」を中心に依存関係を整理することであると思っている。
SOLID原則とか小難しい用語がたくさん出てくるけど、要するにそれはモジュールをどう分割するか、モジュール同士をどう結合するかに関する原則で、Clean Architecture を実践的に導入しようとしたら必要になってくるものだろう。
でも上の図を理解するだけだったら、もっとシンプルに説明できる。
モジュールの依存関係は「変わりやすいもの」が「変わりにくいもの」に依存するようにせよ
だいたいこれだけ押さえておけば、上の図を読み解ける。
円は依存の方向を表現している。円の外側が内側に向かって依存するようになっている。円の中心に Entity と Use Cases が中心にあって、これらがアプリケーションにおいて最も変わりにくいもの、「重要なビジネスルール」である。そして、円の外側に目を向けると、Framework、Web、UI、DB、Devicesなどがある。これらは変わりやすいもの、「詳細」である。
これはちょっと考えると我々が普通に Web アプリケーションを作るのと違った考え方だとわかる。普通は何か Web アプリケーションを作るときにはフレームワークをがっつり依存する。ところが、Clean Architecture は「重要なビジネスルールはフレームワークに依存しないように設計せよ」と言う。
react-clean-architecture の依存関係
具体的に見ていく。モジュールの依存関係とはつまり、モジュールをファイルで分割したときの export / import
の関係のことだ。
eduardomoroni/react-clean-architecture の counter アプリを見よう。
これはシンプルな counter アプリで、ボタンを押すと counter の値が増えたり減ったりするだけだ。
注目したいのは中身の具体的なコードではなく、モジュールの依存関係だ。
counter ディレクトリには core/
と web/
と native/
がある。ビジネスルールが core/
に固められていて、React で実装された web/
と React Native で実装された native/
がそれに依存している。
そして、core/
の中の依存関係はこうなっている。
entities/
が依存関係の中心にある。これは他のいかなるモジュールにも依存しない。外部ライブラリも import しない。
entities/
に依存するのが useCases/
である。これは entities/
にだけ依存している。これまた外部ライブラリを import しない。
Redux フレームワークを使うのは frameworks/
であり、これは adapters/
を介して entities/
と useCases/
に依存している。
このようにして、core/
パッケージはビジネスルールが依存関係の中心にあって、フレームワーク(詳細)が外側に来るように設計されている。Clean Architecture の図のとおりになっている。
ビジネスルールをフレームワークから切り離すメリット
特にフロントエンド開発をしていると日常茶飯事なのが、フレームワークをアップデートしたらアプリケーションが動かなくなるという現象だ。React や Redux は開発サイクルが速いので、たびたび破壊的変更があったりする。
Clean Architecture を杓子定規に採用しなかったとしても、「変わりやすいものが変わりにくいものに依存する」という原則に則って、ビジネスルールをフレームワークから切り離すことにはメリットがあると思う。
ビジネスルールは変わりにくいが、フレームワークは変わりやすい。ビジネスルールがフレームワークに依存していると、フレームワークが更新されるたびにビジネスルールを担当するモジュールにまで影響が及ぶ。
フレームワークを依存関係の外側に押しやっておくことで、フレームワークの更新による影響範囲を限定できる。そういうメリットがある。
そういう意味ではフロントエンド開発にも Clean Architecture を(エッセンスだけでも)導入すれば、メンテコストが下がるかもしれない。