【Flutter】Provider + StateNotifier + Freezed でMVVMのベースプロジェクトを作成した


背景

会社でFlutterの導入に伴い、社内ベースを作成しました。
検討事項は、
- 静的解析
- 設計パターン
- 状態管理
- 標準ライブラリ
- ディレクトリ構成
- 単体テスト

githubはこちら

↑上記作成にあたり、StateNotifierでFlutterの状態管理とユニットテスト入門(CIのおまけつき)を大いに参考にさせていただいております。
ありがとうございます。

静的解析

静的解析ツールとしては、まずは @monoさんの作成されたpedantic_monoを採用しました。

選定理由

  • ライブラリの導入だけで静的解析が導入できる容易さ
  • まずはじめに、著名な方にルールを選定していただいており、それぞれのルールの選定が必要なかった点

今後

今後はプロジェクト開発しながら適切なルールを調整していく予定です。

参考文献

Dart/Flutter の静的解析強化のススメ

設計パターン

今回のベースプロジェクトにはMVVMを採用しました。

選定理由

保守性

さまざまな種類のコードを明確に分離することで、1つまたは複数のより集中した部分に簡単に移動し、心配することなく変更を加えることができます。

テスト容易性

MVVMを使用すると、コードの各部分がより詳細になり、正しく実装されている場合、依存関係は、テストするロジックを含む部分とは別のコードにあります。

拡張性

これには、同様の動作をする新しいコードをアーキテクチャ内の適切な場所に置き換える、または追加する機能もあります。

再利用性

これにより、適切なアーキテクチャが適用されている場合に、アプリケーションでコードを再利用することがより簡単でクリーンになります

参考文献

For Mobile Application Development MVVM is the Clear Winner

状態管理

provider + state notifier + freezedを採用しました。

選定理由

Googleは次のセッションでProviderを状態管理に使うことを推奨している
Pragmatic State Management in Flutter (Google I/O'19)

→2018: Googleのおすすめは、BLoCパターンでした。
 →しかし、RxとStreamがわかりにくい
→2019: Googleは、新しくProviderをおすすめしています。

標準ライブラリ

dio (HTTP クライエント)

simple_logger (ログ出力)

auto_size_text (テキストの動的サイズ変更)

ディレクトリ構造

lib/ 
 ├ common/ 
 ├ config/ 
 ├ utils/ 
 ├ models/ 
 ├ viewModels/ 
 ├ views/ 

  

Common

共通の色の定義やテキストスタイル(フォント)の定義、管理

Config

baseURLやデバイスサイズの設定値の定義、管理

Utils

便利なメソッドの定義、管理
ログ出力メソッドやアラートメソッドなど。

Models

MVVMのモデルに該当する、構造体の定義やビジネスロジックの定義、管理

ViewModels

MVVMのVMに該当する、StateNotifierの定義、管理

Views

MVVMのViewの管理

単体テスト

基本的にModelクラスとViewModelクラスの単体テストを記載
テストコード例)

void main() {
  group('test of counter model', () {
    test('should start from 0', () {
      const counter = CounterState();
      expect(counter.count, 0);
      final nextCounter = counter.increment();
      expect(counter.count, 0);
      expect(nextCounter.count, 1);
    });
    test('should be 0 after 9', () {
      const counter = CounterState(count: 9);
      final nextCounter = counter.increment();
      expect(counter.count, 9);
      expect(nextCounter.count, 0);
    });
  });
}

テスト結果(成功時)

テスト結果(失敗時)

最後に

今後も継続的にメンテナンスしていく予定です。
もし改善提案などいただけたらとてもとても嬉しいです!!

今後

CI/CD関連も記載していきたいです。