最近、依存を少ない形がよいというツイートをよく見る気がする
普段、FlutterとNuxtがメインだけど、
個人開発みたいな少人数・小規模向けだとどういうのがいいのかぁと、
模索を続けていて、ちょっとづつ自分似合う形が見つかってきたので、
備忘録として整理してみた(*´ω`*)
注意
あくまで個人的、かつ、現時点の模索中の状態のもの
どこでもつかえる or 完璧ではないので、
指摘・コメント、Wellcomeです(*´ω`*)
困ってたこと
基本FWの作法に従うほうがよいと思ってるけど、
FlutterとNuxtを行き来すると、
それぞれのお作法を思い出さないといけないのがつらい。。
特に、provider/storeとか、同じ単語だけど、
それぞれのFW/ライブラリの用語の意味が違うものとかがある
FW/ライブラリに依存しない形を考え、
フォルダ構成や用語をFlutterとNuxtで統一できるようになると、
幸せになれるかも?と模索をはじめた感じ
目指していること
- 少人数・小規模向けのほどよい粒度
- FW/ライブラリの用語に依存しない
- FW/ライブラリ問わず使えるディレクトリ構成
- テストしやすい/unitテストできる範囲が多い
ざっくりとした構成
ざっくりとした構成はこんな感じ。エセDDDっぽい。
プレゼンテーション層
画面とかの表示周りの部分。コンポーネント志向を想定
基本は、FWやUIライブラリに依存するものがまとまるイメージ
ルーティングや多言語ライブラリなどのも依存を想定している
登場人物としては、このあたり
- Screen ... 画面
- Component ... UIコンポーネント
- Routing ... 画面のルーティング関連
- Styling ... Design TokenとかThemeとか
- l10n/i18n ... 多言語関連
アプリケーション層
画面やUIコンポーネントから直接呼ばれる状態管理系の部分
基本は、状態管理ライブラリに依存するイメージ
Flutterならriverpod、
Nuxtならpiniaや、composables or inject/provider、
MVVMならViewModelの部分をイメージ
生存期間によって、大きく2種類あり、
- global ... アプリ起動〜終了まで。アプリ全体で利用。認証情報とか
- scoped ... 特定の画面でのみ。sessionとかcontextとかをイメージ
ちゃんと名前を分けたほうがいい気もするけど、一旦、こんな感じ
scopedは、1画面もあるし、フォームみたいな複数画面も想定
ドメイン層
コアでピュアな部分を想定。言語にのみ依存するようにしたい
登場人物としては、このあたり
- Repository(I/F) ... リポジトリのインターフェース
- UseCase/Logic ... 業務ロジック関連
- Exception ... 例外関連
- Entity/Model ... データクラスやenumなど
Entity/ModelはFWやアーキテクチャによって意味合いが変わるので、
悩ましいところ。。
例外の話はこっちでも整理して見てる
インフラ層(インフラストラクチャ層)
DBやAPI、ネットワークなど、外部を扱うものの部分
基本は、各ライブラリに依存するイメージ
登場人物としては、このあたり
- Repository(impl) ... Repository(I/F)の実装
- Service ... 各ライブラリを扱うクラス的なもの
Serviceって単語もFWやアーキテクチャによって意味合いが変わるので、
悩ましいけど、Architecture | Flutterから拝借した形
その他(Utility/misc)
その他、雑多なものをまとめた感じ
loggingやvalidate/formatterなど、
ライブラリを使う想定なので、
基本は、各ライブラリに依存するイメージ
可能であれば、言語にのみ依存するPureな形がよいかもしれない
が、そこに工数を掛ける必要はなさそう?
ディレクトリ構成(仮)
ざっくりとこんな感じ。Flutterには制約がないけど、
Nuxtにはauto-importがあるので、Nuxtベースに近づけてる感じ
- routing/ ... Routing - styles/ ... Styling/Design Token - l10n/ ... l10n/i18n - utils/ ... その他 - constats/ - envronment/ - format/ - logging/ - validate/ - domain/ ... ドメイン/インフラ - exceptions/ ... Exception - models/ ... Entity/Model - repository/ ... Repository(I/F) & Repository(Impl) - services/ ... Service - usecase/ ... UsaCase / Logic - store/ ... Store/State(global) - components ... Component(複数画面で利用するComponent) - pages/ - <foo-bar> - _internal/ ... (Screen固有のComponentなどを配置) - widgets/ ... Component - <foo-bar>Provider.<lang> ... Store/State(scoped) - <foo-bar>.<lang> ... Screen
細かい部分の微調整が必要だけど、大枠はこんな感じをイメージしてる
Nuxtにはauto-importもカスタマイズできるので、よしなにしつつ。。
とりあえず、ざっくり検討中の形を整理してみた(*´ω`*)
これで試してみて、いろいろ改善していこう〜!