👀

Flutterにおける関心の分離(SoC)

2024/10/06に公開

はじめに

自分自身はWebエンジニア出身でFlutterでの開発経験はほぼ皆無なのですが、個人的に最近Flutterの勉強を始めています。

今回はFlutterにおいて関心の分離(SoC)をどう実装するのかについて調べてみました。

分離のケース

この辺りの記事が参考になりました。基本的にはAndroidのガイドにあるようにUI(Presentaion)レイヤー・ドメイン(Domain)レイヤー・データ(Data)レイヤーの3レイヤーに必要に応じてState(ViewModel)を追加して4レイヤーにするクリーンアーキテクチャに寄せる設計が多そうです。

またWidget内のプレゼンテーションロジックについてはhooksを使うとスッキリしそうでした。

https://developer.android.com/topic/architecture?hl=ja
https://developers.cyberagent.co.jp/blog/archives/36149/
https://engineering.dena.com/blog/2024/06/play-by-sports/
https://blog.kinto-technologies.com/posts/2023-12-10-flutter-architecture/

monoさんの記事にあるようにそこまで分ける必要があるのか?という議論はあるものの、いきなり設計原則に基づいた独自のアーキテクチャを提示するよりかは、知っている人の多いクリーンアーキテクチャに寄せて課題が出たら、課題ベースでシンプルにリファクタリングするという流れの方がチームへの浸透のさせ方はやりやすいかなと感じました。この辺は実際にコードを試しに書いてみて肌感を得て考えたいと思います。
https://medium.com/flutter-jp/architecture-240d3c56b597

ディレクトリ構成を機能ファーストとレイヤーファーストのどちらにするか

結論、機能ファーストのディレクトリ構成の方が良さそうです。Next.jsではコロケーションと呼ばれていますが、機能でパッケージし、その内部でレイヤーで分けた方がレイヤーファーストで分ける時に比べて色んなファイルを行ったり来たりしてコードを見る必要が無くなります。

またいらなくなった機能のコードを消す時もfeatureHogeのフォルダを1箇所消すだけで関連コードがすべて消えるので、気楽に消すことができます。

https://codewithandrea.com/articles/flutter-project-structure/
https://qiita.com/honey32/items/dbf3c5a5a71636374567

UI(Presentaion)レイヤーのコンポーネントの分け方をどうするか

UIコンポーネントの分離の粒度もまた悩む所ですが、これもコロケーションの思想でディレクトリを分けていれば、解決する気がします。

よくあるのはAtomicDesign風にコンポーネントを共通化する単位で分ける方法がありますが、本当にそこまで共通化するコンポーネントってあるのかなという問いかなと。

機能単位で粒度は特に気にせずコンポーネントを作っておいて、本当に共通化したいものは/components以下に作っていくくらいのルールで良さそうです。

この辺の考え方はこの記事が近かったです。コンポーネントの共通化というのは言うのは簡単ですが、本気でやろうとするとデザイナーとフロントエンドエンジニアが密にコミュニケーションをとって標準化しないと運用は無理だなと思っていて、今まで色んなチームを見てきましたが、実際に運用できてたチームは数えるほどでした。あまり頑張りすぎない方針でFlutterに関してもいこうと思います。
https://blog.kinto-technologies.com/posts/2023-12-10-flutter-architecture/#がんばらないuiコンポーネントの設計方針を策定

さいごに

関心の分離(SoC)のテーマで先に押さえておきたい観点を書いていきました。

これ以上の解像度にするには実際にコードを書いていくしかないですが、全体像は押さえることができたんじゃないかなと思います。

Discussion