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

Sansan Androidアプリ開発におけるマルチモジュール化の進め方 / Approaches to multi-module development in Sansan Android app

13d936e697fe0f4fa96f926d0a712f6c?s=47 Sansan
PRO
January 13, 2022

Sansan Androidアプリ開発におけるマルチモジュール化の進め方 / Approaches to multi-module development in Sansan Android app

■イベント
iOS/Androidアプリ開発のマルチモジュール化【アンドパッド|クックパッド|Sansan】
https://sansan.connpass.com/event/232503/

■登壇概要

タイトル:Sansan Androidアプリ開発におけるマルチモジュール化の進め方

登壇者:技術本部 Mobile Applicationグループ Androidエンジニア 赤城 史哉

▼Sansan Engineering
https://jp.corp-sansan.com/engineering/

13d936e697fe0f4fa96f926d0a712f6c?s=128

Sansan
PRO

January 13, 2022
Tweet

Transcript

  1. Sansan Androidアプリ開発における マルチモジュール化の進め方 i O S / A n d

    r o i d ア プ リ 開 発 の マ ル チ モ ジ ュ ー ル 化 【 ア ン ド パ ッ ド | ク ッ ク パ ッ ド | S a n s a n 】 Sansan株式会社 技術本部 Mobile Applicationグループ 赤城 史哉
  2. 前職ではAndroidアプリの受託開発に従事。 2019年にSansan入社後、Sansan Android アプリの開発・運用を担当。 赤城 史哉 Sansan 株式会社 技術本部 Mobile

    Applicationグループ 1
  3. 2

  4. Sansan株式会社とは 名刺管理から、営業を強くする 名刺でつながる、 ビジネスのためのSNS 請求書受領から、 月次決算を加速する 設立年 2007年6月 拠点 表参道本社

    Sansan One Sansan パラシオ 関西支店 福岡支店 名古屋支店 資本金 63億33百万円 (2021年8月31日時点) 代表者 寺田親弘(代表取締役社長) 事業 働き方を変えるDXサービス (クラウド名刺管理サービス等)の 企画・開発・販売 グループ会社 Sansan Global Pte. Ltd. (シンガポール) Sansan Corporation (アメリカ) ログミー株式会社 東京証券取引所市場第一部 上場証券取引所 従業員数 979名(2021年8月31日時点) 3
  5. Sansan – 働き方を変えるDX – 4 新世代エントリーフォーム 新世代パンフレット 全文書き起こしメディア 名寄せエンジン Sansan

    Data Hub ピアボーナスサービス 契約書データ化サービス クラウド請求書受領サービス スマート受付 無人名刺受付システム 名刺作成サービス セミナー管理システム クラウド名刺管理サービス スマート署名取り込み AI名刺管理 オンライン名刺 同僚コラボレーション メール配信 イベント・セミナー 請求書 名刺 契約書 組織コミュニケーション 名刺印刷・発注 データ活用 反社チェックオプション powered by Refinitiv/KYCC 契約管理オプション for クラウドサイン 商談管理オプション for Salesforce アンケートオプション powered by CREATIVE SURVEY powered by MotionBoard 名刺分析オプション 業務連携
  6. 本発表のゴール - マルチモジュール導入の具体的な事例を知る - 各々の開発現場での技術的な意思決定の材料とする 5

  7. Agenda - Sansan Androidアプリのマルチモジュール化の現状 - マルチモジュール化の計画 - マルチモジュール化で困ったこと - 様々な規模の開発現場におけるマルチモジュール化との向き合い方

    6
  8. Sansan Androidアプリの マルチモジュール化の現状

  9. - 名刺管理 - スマホのカメラを使って名刺登録 - 登録した名刺に関連する企業のニュースを確認 - 商談メモや議事録 (コンタクト機能) -

    社内チャット - 企業情報の閲覧 - 同僚一覧を閲覧 アプリの主な機能 8
  10. - ファイル数 - Kotlin : 約3000ファイル - Xml : 約1000ファイル

    - コード行数(Kotlin) - Kotlin : 約16万行 - Xml : 約5万行 - モジュール数:80モジュール - エンジニア数:7名 - アーキテクチャ:Flux + Clean Architecture Sansanアプリ開発の現状 9
  11. すごく便利!!! おかげで、快適な開発が出来ている。 Gradleさんありがとう!!!! マルチモジュール化の恩恵(1エンジニアの感想)

  12. - 開発の大規模化 - 複数人での並列的な機能開発による諸問題 > コンフリクトの増加 > アーキテクチャのルールが守られなくなる懸念 - コードの肥大化による諸問題

    > ビルド時間の増加 > コードの読みづらさ > 改修・調査するファイルの見つけづらさ アプリ開発における課題 11
  13. - ビルド時間の短縮 - レイヤー間の依存関係の強制 - 各モジュールの関心事を小さくできる - packageではクラスのグルーピングしか出来ないが、レイアウトファイルや resource等も含めたグルーピングが可能 マルチモジュール化のメリット

    12
  14. - 差分ビルドの時間が約半分に - legacyを触るときはまだ遅い - string.xmlやlayoutファイル、Android Manifest等の情報が 機能単位に集約され、見やすい - ノイズが少なく、担当している機能に集中できる

    - internal修飾子による、モノリスより柔軟な可視性の制御 - モジュール追加のタイミングで、アーキテクチャのレイヤーが 守られる事を担保 マルチモジュール化の恩恵 13
  15. Sansanアプリ開発の現状:マルチモジュールの構造 14 :app :legacy :repository :data:repository_impl :data:local :data:network :resources :xx_util

    :router :domain :feature:bizcard :feature :company :feature :company_common
  16. :legacy :repository :data:repository_impl :data:local :data:network :resources :xx_util :router :domain :feature:bizcard

    :feature :company :feature :company_common Sansanアプリ開発の現状:マルチモジュールの構造 15 :app 全てのモジュールに依存 Daggerによる依存性の解決を行う
  17. :app :legacy :repository :data:repository_impl :data:local :data:network :resources :xx_util :router :domain

    :feature:bizcard :feature :company :feature :company_common Sansanアプリ開発の現状:マルチモジュールの構造 16 :legacy :feature:bizcard :feature :company :feature :company_common Presentationレイヤー Activity, Flux etc… Featureは画面・機能に切り分け
  18. :legacy :repository :data:repository_impl :data:local :data:network :resources :xx_util :router :domain :feature:bizcard

    :feature :company :feature :company_common :app Sansanアプリ開発の現状:マルチモジュールの構造 17 Domainレイヤー その他各featureモジュール が共通して使うクラス :repository :resources :xx_util :router :domain
  19. :legacy :repository :data:repository_impl :data:local :data:network :resources :xx_util :router :domain :feature:bizcard

    :feature :company :feature :company_common :app Sansanアプリ開発の現状:マルチモジュールの構造 18 Dataレイヤー SharedPreference, Retrofit など を取り扱う実装 Presentationレイヤーから 直接依存されない :data:repository_impl :data:local :data:network
  20. :legacy :repository :data:repository_impl :data:local :data:network :resources :xx_util :router :domain :feature:bizcard

    :feature :company :feature :company_common :app Sansanアプリ開発の現状:マルチモジュールの構造 19 実態は、featureがdataレイヤーを参照していたり、 その他のモジュールも存在していて複雑。こちらは基本的なコンセプト。 このコンセプトにそう実態になるよう、日々改修している。
  21. マルチモジュール化の計画と実行

  22. - STEP 1 : domainのみを分離 - STEP 2 : data関連のモジュールを分離

    - STEP 3 : UI関連のコードをlegacyに移動 - STEP 4 : Repository, Routerのinterfaceを切る - STEP 5 : UIのコードを機能ごとに分割 マルチモジュール化の5ステップ 21
  23. STEP1 : domainのみを分離 22 :app

  24. STEP1 : domainのみを分離 23 :resources :xx_util :domain :app

  25. STEP2 : data関連のモジュールを分離 :app :data:local :data:network :resources :xx_util :domain 24

  26. STEP3 : UI関連のコードをlegacyに移動 :app :legacy 25 :data:local :data:network :resources :xx_util

    :domain
  27. STEP4 : Repository, Routerのinterfaceを切る :app :legacy 26 :data:local :data:network :resources

    :xx_util :domain :router :repository :data:repository_impl
  28. STEP5 : UIのコードを機能ごとに分割 :app :legacy 27 :data:local :data:network :resources :xx_util

    :domain :router :repository :data:repository_impl :feature :bizcard_common :feature :company :feature:bizcard
  29. STEP5 : UIのコードを機能ごとに分割(完成形) :app 28 :data:local :data:network :resources :xx_util :domain

    :router :repository :data:repository_impl :feature :company_common :feature :company :feature:bizcard :feature:piyo :feature:hoge :feature:fuga
  30. マルチモジュール化で困ったこと

  31. - モジュール化の認識をチームで合わせる必要性 - 共通化されたクラスを使いたい時、循環依存を回避するのが難しい - 意図せずデグレしてしまう事がある 困ったことのカテゴリ 30

  32. - モジュールの切り方が分からない - 作成方法のドキュメントを用意しておく - モジュールの切る粒度 - 都度議論して方向修正していく - 新規開発でのモジュールの切り方、モジュール名の付け方

    - 開発時に、詳細設計レビューを実施している。 その際にモジュール設計もレビューする モジュール化の認識をチームで合わせる必要性 31
  33. 循環依存を考慮した設計をする必要がある 会社詳細画面のモジュールに、新しく名刺の一覧画面を作ることになり 既存の名刺レイアウトを流用したい場合 32 :feature:会社詳細 (new) 会社に紐づく名刺一覧画面 :feature:名刺詳細 名刺レイアウト.xml

  34. 循環依存を考慮した設計をする必要がある 会社詳細画面のモジュールに、新しく名刺の一覧画面を作ることになり 既存の名刺レイアウトを流用したい場合 33 :feature:会社詳細 (new) 会社に紐づく名刺一覧画面 :feature:名刺詳細 名刺レイアウト.xml implementation

    project(”:feature:名刺詳細”)
  35. 循環依存を考慮した設計をする必要がある 名刺詳細でも、会社詳細に依存したいケースが出てきてしまうと… 34 :feature:会社詳細 (new) 会社に紐づく名刺一覧画面 :feature:名刺詳細 名刺レイアウト.xml implementation project(”:feature:会社詳細”)

    implementation project(”:feature:名刺詳細”)
  36. 循環依存を考慮した設計をする必要がある 35 名刺詳細でも、会社詳細に依存したいケースが出てきてしまうと… :feature:会社詳細 (new) 会社に紐づく名刺一覧画面 :feature:名刺詳細 名刺レイアウト.xml implementation project(”:feature:会社詳細”)

    implementation project(”:feature:名刺詳細”) コンパイルエラーになってしまう
  37. 循環依存を考慮した設計をする必要がある Sansan Androidでは、feature_commonモジュールを作り解決 36 :feature:名刺_common 名刺レイアウト.xml :feature:会社詳細 (new) 会社に紐づく名刺一覧画面 :feature:名刺詳細

  38. - シングルモジュールのアプリではコンパイルできた依存関係でも、 マルチモジュールに移行するとエラーになってしまう - 注意しながら依存関係を設計しないと、すぐに複雑なモジュール間の 依存関係が作り出されてしまい、負債となる 循環依存を考慮した設計をする必要がある 37

  39. 意図せずデグレしてしまう事がある :feature:名刺詳細 :feature:会社詳細 strings.xml strings.xml 38

  40. 意図せずデグレしてしまう事がある 39 :feature:名刺詳細 :feature:会社詳細 strings.xml strings.xml string.xmlなどのresource idがコンフリクトすると、 片方のresourceが上書きされてしまう

  41. 意図せずデグレしてしまう事がある 40 :feature:名刺詳細 :feature:会社詳細 strings.xml strings.xml マルチモジュール環境では、resource id はユニークにする必要がある

  42. 意図せずデグレしてしまう事がある resource prefix機能を使うと、そのモジュールの中のresource id にprefixを 設定できる。 41

  43. 様々な規模の開発現場における マルチモジュール化との向き合い方

  44. - 今までのセクションは、あくまでSansan Androidアプリ固有の話 - 様々な開発現場のシチュエーションを想像して、マルチモジュール機能を どのように使うか、考えてみましょう! - Twitterで #ANDPAD_cookpad_Sansan タグをつけて

    @ginyolith_tech の アカウントでツイートするので、同じくタグを付けて、お題に対する回答 を引用リツイートお願いします! - 経験豊富な方は初心者時代の自分と同じような人を助ける気持ちで、 マルチモジュール初心者の方は自分で考えるトレーニングとして、 ぜひツイートしてください! このセクションについて 43
  45. - エンジニアの人数:1人(あなた) - アプリ開発のアイデアがあり、これから作っていく 技術選定のフェーズ - とにかく早くリリースをして欲しいという社長からの要望 開発現場1 創業したてベンチャー企業で1人エンジニア 44

  46. - マルチモジュール化には向き合わなくて良い - とにかくリソースが無いことが想像できる - マルチモジュール化は詰まりどころが多い - コードベースが小さいのであれば、ビルド速度は問題にならない - 余裕があれば、packageでの最低限のレイヤー分けが出来ていると良い

    - ViewModel, Repository等 - 補足: 初心者の場合は、他の技術(coroutineやcompose等)を優先して学習すべき 開発現場1 自分の考え 45
  47. - エンジニアの人数:2~3人(あなた + 中堅エンジニア2, 3人) - 半年程度でアプリを完成させ納品する契約 - 要件やデザインは決まっており、これから技術選定する段階 -

    納期には多少余裕がありそう - 納品した後は大きなアップデートの予定は無い バグ修正程度の依頼がちょくちょく来る想定 開発現場2 中規模な受託開発案件 46
  48. - レイヤー分けレベルのマルチモジュール化はした方が良い - 納期間際でのバグ修正や仕様変更に対応したい - アーキテクチャをある程度守らないとバグになりやすい規模感 - 機能単位のモジュール化は余裕があればしてもよさそう - コンパイルが通らなくなったり、循環依存の問題が出やすいので注意

    開発現場2 自分の考え 47
  49. - エンジニアの人数:4人(あなた + ベテラン、中堅、ジュニア各1) - 技術的負債が大きく、新機能の開発に工数がかかるのを解消したい - コードベースが大きくなっており、ビルド時間がかかるのがストレス - 最近はアーキテクチャを導入してきれいなコードになっているが、

    一部の昔のコードはFat Activityなどつらいコードが存在する - 定期的に新機能の開発を行っている - アーキテクチャやライブラリなどを刷新する計画が立っている。 その技術選定を考えるフェーズ 開発現場3 中規模な事業会社でのリアーキテクチャ 48
  50. - 計画的にマルチモジュール化に向き合ったほうが良い - アーキテクチャを考え直すのとセットで向き合うと良い - モノリス -> モジュール化は工数が結構かかるので注意 - featureモジュールも作ったほうが良い

    - 機能開発と並行してモジュール化をする場合 - ビルド速度に関しては、即時の対応としてマシンスペックを上げるのも手 > M1Macだと大分変わる 開発現場3 自分の考え 49
  51. まとめ - マルチモジュール機能は大規模な開発現場における協力な味方 - 一方で、もちろん銀の弾丸ではない メリットデメリットを正しく検討して導入しよう - 巨大なモノリスからのモジュール化は計画をきちんと建てて行うと良い 50

  52. エンジニア情報サイト「Sansan Engineering」 51 ・Sansanエンジニアのミッション ・プロダクト、テクノロジー概要 ・エンジニアインタビュー ・技術スタック ・働く環境、社内制度 ・募集職種 ・Blog

    ・イベント情報 ... and more Sansan Engineering Sansanのプロダクトやテクノロジー、カルチャー、採用情報など、エンジニアリングに関するあらゆる情報を掲載 https://jp.corp-sansan.com/engineering/
  53. ※ 登録の際、紹介コードの欄に「0 1 1 2 勉強会」と入力ください。

  54. None