Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Multi-module design of Kauche Android

Multi-module design of Kauche Android

sintario

July 13, 2022
Tweet

More Decks by sintario

Other Decks in Technology

Transcript

  1. © KAUCHE, Inc. Table of Contents - 自己紹介 - Kauche

    のざっくりした紹介 - Kauche Android の歩みと選択 - 初期スタートアップなりの取捨選択 - 生産性を高めるために気がついたらマルチモジュールになっていた話 - Kauche に今も残る課題 - まとめ
  2. © KAUCHE, Inc. Self-introduction sintario as a service - 社歴

    - Oct. 2020 複業で join - July 2021 正社員に - July 2022 Product unit, Social UX team - それ以前 - ex-mercari, ex-DeNA, ex-JustSystems - A mobile-app engineer - Android 主に書く - iOS 最近はちょっと書く - 直近だと6月リリースの超シェア買い祭(タイムセール)を Android と iOS 両方 泣きながら 実装した者です - A remote contributor - ほぼ出社してません(交通費精算回数数えたら 5回 / 1年)
  3. © KAUCHE, Inc. Kauche 1.0.0 (MVP) リリース前の開発中の貴重なスクショ 最初は検索すらない強気のECアプリ - 商品一覧

    - 商品詳細 - 決済画面(shopify, custom tabs) - グループ詳細 - 使い方ガイド - 設定
  4. © KAUCHE, Inc. Architecture overview - 在庫管理・陳列・決済を shopify で 実現

    - カウシェのサーバーがシェア買いグ ループを実現 - shopify の rate limit が厳しい、アプ リから直接 SDK 経由で叩く - BFF がアプリ側にいるような構成 customer API by Kauche storefront API by shopify Product Group, Product ID Product ID
  5. © KAUCHE, Inc. Kauche 1.0.0 - core - data class

    の寄せ集め - ユーティリティ関数とか - api - customer API client - api_java - customer API は protobuf で定義されている - protobuf から生成されたモデルクラス - design - デザイン定数とか - shopify - storefront API client - app - その他全部
  6. © KAUCHE, Inc. Android app’s architecture (初期) - Single Activity,

    Fragments, ViewBinding, Jetpack Navigation - 購入経路が商品詳細とグループ詳細の 2系統ある - custom tabs で開いた shopify の決済画面からアプリに戻すため launchMode=singleTask にしておいて url scheme で戻 る - url scheme で戻ったあと LocalBroadcastReceiver で購入元画面に更に制御を戻す - MVVM の中身を clean architecture っぽく階層分割したもの
  7. © KAUCHE, Inc. 組織の課題も踏まえて進み方を考える - まだまだ何にもない、これから作るもののほうがモリモリ - 求められているのは Try First

    をモリモリできる生産性 - どんどん作る・失敗しても作り直す・捨てるコードもあって当たり前 - Android は社員が自分一人、 iOS は専任正社員が実質いない - 潤沢な人的リソースがあったときにスケールするアーキテクチャはまだいらない - 複業メンバーに活躍してもらうことを前提に最適化する - 本業が他にある人には 1日 2 - 3 時間使ってもらえたらいいほう - 長考に陥らないようにしたい - 明快であること - 作るものをできるだけ減らす - 関心の分離 - やることを小さくする - 影響範囲を小さく - 開発にハマれること(サービスの魅力+書き心地+チャレンジ精神) - (結果的に自分自身の生産性をも引き出すこと)
  8. © KAUCHE, Inc. Feature Flags - 作りかけでもどんどん merge できるようにする -

    細切れの時間で作っている人が epic ブランチを長期保持するような開発は非現実的 - develop ブランチに入っていれば常勤社員がビルド通るように非同期保守できる - (複業メンバーの経験値から、 PRを小さくする実践力は期待できる前提) - どんどんPRレビューしてどんどん merge する進捗感が煽る生産意欲 - release blocker にさせない - 理想形は目指さない - ABテストフレームワークとの統合とか贅沢言わない - 遠隔操作できるのが理想だが、そこまでなくてもいい - アプリ上で ON/OFF できる UI 作るのも最初はいらない - FF自体が信頼できるか、を検証する工数もタダではない - kill switch としての Feature Flags があればよい - ON/OFF 切り替えできれば十分
  9. © KAUCHE, Inc. Jetpack Compose 導入 - エンジニアのやる気と生産性を引き出す - 宣言的

    UI 便利だよ、楽だよ、楽しいよ - 新しいものが触れているよ - 複業でチャレンジできているよ、を嘘にしない - 案外リプレイスに(外の世界では)推進力いる - すでにお金を稼いでいるアプリにおける、やらなくても動き続けるのになんでやるの?への説得 - 稼いでないアプリではなおさら - 機能開発を優先されるとコード改善が延々進まない無間地獄 - そもそも投資的エンジニアリングへのやる気が必要 - カウシェのバリューの体現という後押し - Try First - Enjoy Working - For Team
  10. © KAUCHE, Inc. 安全な Jetpack Compose migration Feature Flags と

    ComposeView を組み合わせて使う - ViewModel はちゃんとデザインしていれば流用できる - 元の Fragment の機能を温存したまま UI を丸々入れ替える形で作る - migration も進むし検証終わるまで隠蔽もできるし、エンジニア主導の技術転換もこっそり進めや すい
  11. © KAUCHE, Inc. マルチモジュール化 : feature modules導入 - app に全部

    feature 実装が集まると嬉しくないことを緩和したい - すべてのクラスが原則見えてしまうので何でもできすぎる - 探しものに時間がかかるようになる - あとから解消がむずかしい依存の発生を回避しにくくなる - 作業領域の交差 - namespace の奪い合い - 生産的な意味で「させない」構造を作る - 余計なものを見えなくする - 探せる範囲を小さくする - 依存できなくする - 作業の交差を小さくする - feature ごとに固有の package
  12. © KAUCHE, Inc. module 分割 - analytics - クライアントログとか -

    navigation - (一部の)画面遷移実装 - deeplink 定義 - core - repository interfaces - data classes - その他データ状態仕分け便利クラス LoadState とか - design - Composable 関数で定義した再利用性の高い共通 UI - feature_foo_bar - いわゆる feature module - 原則新機能を作るときには新しくモジュールを立てる
  13. © KAUCHE, Inc. feature module の build.gradle.kts - analytics, core,

    design, navigation にのみ依存OK - repository などは DI で app から差し込まれる - 他の feature module に依存するのはナシ - navigation-compose と navigation-fragment を併用 - 既存 app 実装をできるだけ活かしつつ、 new feature を実装資産化 する - プロフィール作成画面 - アイコン選択画面は navigation-compose
  14. © KAUCHE, Inc. 例: feature_mission - ユーザーアクティビティに対して報酬 クーポンを付与する活性化策 - v1.33.0,

    May 25, 2022. - feature flag を入れて実装して実は一ヶ月前 くらいには Android が先行して完成していた - 達成判定はバックエンド - ミッション詳細・報酬詳細は web - アプリ側は実質ミッション一覧画面のみ - 未達ミッション、残時間カウントダウン - 達成後の報酬受取 - 流入経路が複数ある・増えうる
  15. © KAUCHE, Inc. app: nav_graph.xml - nested graphにする。 - action

    書かない(ほとんど明示的接続をしない) - 画面間でオブジェクトを渡さないといけないときだけ app 側で <fragment> と action を書く
  16. © KAUCHE, Inc. host fragment - app の nav_graph で規定された

    deepLink や一般的な web への遷移を扱うため navigator を app で実装して DI - host fragment は fragment の navigation を差し込むための皮、画面は実質 Jetpack Compose 実装
  17. © KAUCHE, Inc. MissionListScreen の中身の抜粋 - 概略さらさら読める作り - viewModel.state に応じて

    loading, error, list, 空 を出し分けるだけ - 依存を限定したことで簡素化・標準化 - MissionViewModel / MissionUseCase あたりにビジネ スロジックが集まるが、そっちもやることほとんどない薄 い実装 - 圧倒的にあっという間に開発終わる - 保守も楽
  18. © KAUCHE, Inc. 2022年の夏を迎えて : 今も残る課題感 1. client-side BFF 問題

    2. grpc-gateway で GET を使うとおいしくない 3. いつ Fragment をすべて駆逐できるか
  19. © KAUCHE, Inc. 課題: Client-side BFF - BFF がアプリ側にいるような構成 -

    つまりアプリ側に分厚いロジックが ある - APIデータ合成ロジックはアプリケー ション側で気にしたくない customer API by Kauche storefront API by shopify Product Group, Product ID Product ID
  20. © KAUCHE, Inc. 課題: Improved architecture…? customer API by Kauche

    storefront API by shopify Product Group, Product ID Product ID UseCase getGroupDetail GroupDetail 明瞭さや 再利用性を高めることは できるかもしれないが 順番に2API呼ぶしかないのが解決してない
  21. © KAUCHE, Inc. 課題: grpc-gateway https://github.com/grpc-ecosystem/grpc-gateway - gRPC を RESTful

    JSON API として呼べるようにしてくれる - カウシェアプリからのリクエストは現況 RESTful の方を使ってい る
  22. © KAUCHE, Inc. 対策 一律 POST を最近採択した - 取得系の API

    を含めてすべての RPC で POST を使う - リクエストパラメタは body となるので proto の型をそのまま使って Retrofit に @Body で指定できるようになる - 一律でPOSTを使う際、エンドポイント名にRPC名をそのまま用いる - RESTful で GET /foos のようなリスト取得だったものを単純に POST に変えるとリソース生成とエンドポイント衝突が起き てしまうため - つまり grpc-gateway を RESTful API 提供の手段ではなく JSON API の提供手段と割り切る あるいは、アプリが gRPC を直接しゃべるという方向性も?
  23. © KAUCHE, Inc. 課題: Fragment の駆逐 正直 Fragment ある方がまだ便利なこともあるのでもうしばらくは Fragment

    併用で - Fragment の中に Composable 関数を定義すれば Context とか Activity とかも不都合なく取得 できる - Jetpack Compose だけで閉じない(機能が足りない)こともまだあるので
  24. © KAUCHE, Inc. 残る課題感とどう向き合うか - 通信・全体アーキテクチャ - architect yuki.ito join!

    大きな解決を目指していく - Android 固有の課題 - プラットフォームの成熟を待つ - Google の new release を追いながら - Try を止めない
  25. © KAUCHE, Inc. まとめ - カウシェとそのアーキテクチャのご紹介をしました - 気になる商品を誰かと買うシェア買いの最小構成要素は意外とシンプル - 一方で、2

    API servers 併用の複雑性 - カウシェ Android が生産性を引き出すために行ったマルチモジュール化をご紹介しました - 複業主体のチームでは 短い時間で迷いなく安全に成果を積み上げられる技術採択 がおそらく正解 - Feature Flags: 変更を安全に隠す - Jetpack Compose: UIの資産化、生産時間効率を高める - マルチモジュールと deep link navigation: 関心範囲を限定する・柔軟な呼び出し - 残課題はありますが Try First を続けていきます カウシェではモバイルアプリエンジニアを積極採用中です ご興味あれば弊社採用ページをぜひ御覧ください https://enjoy-working.kauche.com/