Flutterを技術スタックに加えてアプリチームは加速する #1 導入編
こんにちは、エンジニアのhoriです。
2022年の目標は「何かしらレースに出る」なので最近国内A級ライセンスを取りました。
この度、SPACEMARKET for HOSTをFlutterでリプレイスしました。
アプリの内容は、スペースマーケットに「スペースを掲載するユーザー(ホストユーザー)」を対象に、
・やることの管理
・カレンダーでのスケジュール把握
・予約の確認・対応
・収益確認
をもっと簡単かつスムーズにしていただこうというものです。
App Store はこちら
Google Play はこちら
はじめに
アプリチームでは初めて本番環境でFlutterを採用したので、
・導入編 技術選定とアーキテクチャ(今回)
・開発編 コードサンプル。進める上での良かった事・問題・反省点
・運用編 新たな技術を入れる上でのチームビルディング
という3本立てで、どんな風にFlutterと向き合い、付き合っていくことにしたのかというご紹介をしていきたいと思います。
技術選定とアーキテクチャ
Flutterの採用理由
最初にやりたいと手を挙げたのは私自身なのですが、以下の理由でした。
・リプレイス前のアプリはWebViewアプリだったのでネイティブ化したい
・Flutterを採用する事例が増えている(2.0系になってから特に)
・実際に自分でアプリを作ってみて、純粋なネイティブアプリと比べて遜色ないアウトプット&開発しやすさ
→ 過去にReact Nativeを採用した経験があったがそれより開発体験が良かった(主観)
ということで、アプリエンジニアのリソース不足🙈 という事情もあり、「新規ネイティブアプリを作るならFlutterでいきましょう!」という感じになりました。
アプリのアーキテクチャ
今回のアーキテクチャはざっくり図にすると以下のようになっています。
ポイントにしているのは
・DDDを意識したレイヤードアーキテクチャ
・MVVM + Flux
・Flutter 2.0、Navigator 2.0、riverpodの採用
という点です。
DDDを意識したレイヤードアーキテクチャ
上記の図には登場していませんが、ドメイン知識を表現するモデルクラスは全てentityとして定義しています。
・「ステータスコードがXXである予約は承認済みである」
・「スペースのプラン名は時間貸しならA、宿泊ならB」
などです。
また、domain層がinfra層(今回だとAPIのレスポンスの型など)に依存しないように、Repositoryを使ってdomain層が一番内側になるような依存関係としています。
[参考] Clean ArchitectureをNode.js+Typescriptで実装してみる
またアプリの外の世界とのやりとりが、REST APIもあればGraphQLもあればFirebaseもある、という状態だったのでそのような外の世界のカオスをRepositoryで吸収するという鉄板のパターンでした。
MVVM + Flux
コードの量は増えてしまいますが、今回はMVVMとFluxを両立させることで以下の効果を目指しました。
・widgetの組み立てとUIのロジックを分離する
→ ロジックをViewModelに集中させ、widgetはUI構築のみに集中する
・UIに関するロジックと状態に関するロジックを分離する
→ まずは状態に関するロジックだけでもユニットテストを書ける
・Reactの開発経験からFluxベースのアーキテクチャの知見を活かす
→ 宣言的UIで実装するアプリケーションでのベストプラクティスなど
実際にやってみたところ、以下のメリデメを感じました。
メリット
・UIデザインが未定の場合でも仕様は決まっているので、状態に関するロジックの開発&テストを先に進めることができる
・UIロジックが分離されているのでwidget自体の見通しが良くなる
デメリット
・絶対的なコード量は多くなる
・widgetを使い回したくなったときにロジックによっては流用できないのでコピペしてしまう恐れがある
個人的には、総じてメリットの方が高かったなと思っています。
Flutter 2.0、Navigator 2.0、riverpodの採用
今回は開発当初からFlutter2.0系がリリースされていたため、2.0系で開発を開始しました。
リリースまでに2.5.0までアップデートがあり、その度に追従していったのですが、ライブラリによってビルドできなくなる場合もあったので注意ポイントです。(開発編で詳しくご紹介します)
画面遷移には Navigator 2.0 に対応しました。
従来の画面遷移の仕方と違って、画面のスタックを「状態」として扱うことでルーティングを実現しています。
状態の伝搬とモジュール間の依存解決(DI)にriverpodを採用しています。
具体的にどう実装しているか、つまづいたポイントなど開発編で紹介したいと思います。
今回のまとめ
Flutter製アプリをリリースしました!
MVVM + FluxなアーキテクチャでDDDな思想でアプリ開発しています。
次回「開発編」で実際のコードサンプルや躓いたポイントなど紹介します。
お知らせ
モバイルアプリエンジニア採用中です!
Swift、Kotlin、Dartなどマルチにやってみたいアナタを待ってます!
この記事が気に入ったらサポートをしてみませんか?