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

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

## githubはこちら
https://github.com/Tetsukick/flutter_state_notifer_MVVM_sample

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/272d5350-89dd-569b-f786-f27242e619b4.png)

↑上記作成にあたり、[StateNotifierでFlutterの状態管理とユニットテスト入門（CIのおまけつき）](https://qiita.com/glassmonkey/items/0a406898cd28152c24ff)を大いに参考にさせていただいております。
ありがとうございます。

## 静的解析
静的解析ツールとしては、まずは [@monoさん](https://twitter.com/_mono)の作成された[pedantic_mono](https://pub.dev/packages/pedantic_mono)を採用しました。

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

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

### 参考文献
[Dart/Flutter の静的解析強化のススメ](https://medium.com/flutter-jp/analysis-b8dbb19d3978)

## 設計パターン
今回のベースプロジェクトにはMVVMを採用しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/03461c3a-1de3-a2f4-94d3-81ac44c99cbd.png)

### 選定理由
#### 保守性
さまざまな種類のコードを明確に分離することで、1つまたは複数のより集中した部分に簡単に移動し、心配することなく変更を加えることができます。
#### テスト容易性
MVVMを使用すると、コードの各部分がより詳細になり、正しく実装されている場合、依存関係は、テストするロジックを含む部分とは別のコードにあります。
#### 拡張性
これには、同様の動作をする新しいコードをアーキテクチャ内の適切な場所に置き換える、または追加する機能もあります。
#### 再利用性
これにより、適切なアーキテクチャが適用されている場合に、アプリケーションでコードを再利用することがより簡単でクリーンになります

### 参考文献
[For Mobile Application Development MVVM is the Clear Winner](https://blog.makingsense.com/2017/04/for-mobile-application-development-mvvm-is-the-clear-winner/)

## 状態管理
provider + state notifier + freezedを採用しました。

### 選定理由
Googleは次のセッションでProviderを状態管理に使うことを推奨している
[Pragmatic State Management in Flutter (Google I/O'19) ](https://www.youtube.com/watch?v=d_m5csmrf7I)

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

## 標準ライブラリ
#### dio (HTTP クライエント)
https://pub.dev/packages/dio

#### simple_logger （ログ出力）
https://pub.dev/packages/simple_logger

#### auto_size_text （テキストの動的サイズ変更）
https://pub.dev/packages/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クラスの単体テストを記載
テストコード例)

```dart:
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/97d520c8-d10a-e24e-0fb0-5ea454cc5ef3.png)


#### テスト結果（失敗時）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/7862305b-afe0-d577-6aba-147af860a157.png)

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

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