最近、依存を少ない形がよいというツイートをよく見る気がする
普段、FlutterとNuxtがメインだけど、
個人開発みたいな少人数・小規模向けだとどういうのがいいのかぁと、
模索を続けていて、ちょっとづつ自分似合う形が見つかってきたので、
備忘録として整理してみた(*´ω`*)
注意
あくまで個人的、かつ、現時点の模索中の状態のもの
どこでもつかえる or 完璧ではないので、
指摘・コメント、Wellcomeです(*´ω`*)
こちらの記事をfreelance hub様に紹介いただきました🎉🎉
困ってたこと
基本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もカスタマイズできるので、よしなにしつつ。。
とりあえず、ざっくり検討中の形を整理してみた(*´ω`*)
これで試してみて、いろいろ改善していこう〜!