FlutterのproviderパターンにてCleanArchitectureを学ぶ



チュートリアルの流れ

設計手法


- ビジネスロジックをUI, DB, network, 3rdパーティーpackageから分離する
- 理由: コアのビジネスロジックは変化しにくいから
- UIはWebAPIに直接アクセスしてはいけない
- 至るところからDBを呼ぶ状態にしてはいけない
- 方法: プラグイン的な設計にする
- モバイルUIをデスクトップUIに入れ替えられる
- DBを入れ替えられる
- local storageを入れ替えられる

State Management と Provider


- このチュートリアルで扱うアプリケーションはこのような構成になる
- Local Storage
- web API
- UI
- ビジネスロジックがState managementをする
- providerはそのState managementのhelperとなる
- ChangeNotifierProviderによりUIビジネスロジックを挿入する

ビジネスロジックによる連携

  • MVVM
    • Data層がModelとなる(赤)
    • ビジネスロジックがViewModelとなる(紫)
    • UIがViewとなる(緑)
  • UIはViewModelの変更の通知を受ける
  • UIはViewModelにイベントを送る
  • ViewModelはUIがどういうものかに関知しない
  • ビジネスロジックはサービスのインターフェイスに対する処理をする
    • ローカルストレージかWebかについてビジネスロジックは関知しない
    • この形式はRepository Patternとも呼ばれる

Service Locator

  • get_it packageを用いる
  • 制御の反転、依存性の逆転を目的とする
  • ビジネスロジックから実装する際、未実装のServiceはFakeを作成する
  • 実装後に簡単に入れ替えられる
// 開発開始時にはFakeを用いる
// serviceLocator.registerLazySingleton<CurrencyService>(() => CurrencyServiceFake());

// Serviceが実装できたら入れ替える
serviceLocator.registerLazySingleton<CurrencyService>(() => CurrencyServiceImpl());

学んだこと

  • CleanArchitectureの観点でMVVMを実装すると、ModelとViewがそれぞれViewModelに依存する
    • ViewModelがビジネスロジックとなる
  • ViewModelがData層(Model)を扱う場合、そのインターフェイスにのみ依存する
    • 理由: ビジネスロジックであるViewModelは変化しにくいものであるから、Model等の他のオブジェクトに依存させたくないため
    • つまり、制御の反転を行うためにインターフェイスに依存する
    • 実装はService Locatorを用いて注入する
  • 開発時は未実装のService(Data層)のFakeを作成する
    • WebAPIから取得するModelのFakeとしては、ダミーのListを返すものやダミーのJSONを読み込むものを作成する
      • 実装が終わればFakeと置き換える
      • VMがMのインターフェイスにのみ依存しているので置き換えが容易となる
    • TDDではTestにてmockを作るが、このmockと同じ役割となる