LoginSignup
81
69

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-07-19

背景

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

githubはこちら

image.png

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

静的解析

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

選定理由

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

今後

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

参考文献

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

設計パターン

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

選定理由

保守性

さまざまな種類のコードを明確に分離することで、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);
    });
  });
}

テスト結果(成功時)

image.png

テスト結果(失敗時)

image.png

最後に

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

今後

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

81
69
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
81
69