Save 37% off PRO during our Black Friday Sale! »

Baby steps to improve architecture in Study Sapuri Android

04ab1563ccc36f66ebea3b2a0e3488b9?s=47 chiiia12
February 05, 2020

Baby steps to improve architecture in Study Sapuri Android

04ab1563ccc36f66ebea3b2a0e3488b9?s=128

chiiia12

February 05, 2020
Tweet

Transcript

  1. #sapurimeetup Baby steps to improve architecture In Study Sapuri Android

    @chiiia12 Study Sapuri/Quipper Product Meetup #4
  2. #sapurimeetup @chiiia12 / 横尾千明 2 • Mobile Engineer at Quipper

    ◦ 2018.4 Study Sapuri Android team join ◦ Quipper Product Team Blogの運営 • 2015年新卒でエンジニアとしてリクルート入社 ◦ お小遣い稼ぎサービスでサーバーサイド開発 ◦ 人材領域でAndroidアプリ開発 Baby steps to improve architecture In Study Sapuri Android
  3. #sapurimeetup 今日お話しすること ➔ 歴史ある大規模 Android アプリにおけるアーキテクチャ改善 ◆ 案件開発・リリースを止めずに進める戦略 ◆ リファクタリングを進めていく中での試行錯誤

    ◆ アーキテクチャ改善で得た思わぬ恩恵? 3 Baby steps to improve architecture In Study Sapuri Android
  4. #sapurimeetup Agenda | 01 02 03 04 Androidチームの現状と技術的課題 どのように実践していくか Try

    & Error 振り返り・まとめ 4 Baby steps to improve architecture In Study Sapuri Android
  5. #sapurimeetup Androidチームの 現状と技術的課題 01 5 Baby steps to improve architecture

    In Study Sapuri Android
  6. #sapurimeetup Androidチームについて • EM1名、メンバー4名 • メンバーは全員Quipper歴2年以内 6 @daisukefuji @chiiia12 @padobariya

    @aruke @geckour Baby steps to improve architecture In Study Sapuri Android
  7. #sapurimeetup • 小中高大学受験生向けの学習アプリ • ユーザータイプ: 5タイプ • ソースコード:135,125行 • 現ソースコードでの開発:5年以上

    • 歴史と複雑さを持つアプリ Study Sapuri について 7 Baby steps to improve architecture In Study Sapuri Android
  8. #sapurimeetup 手をつけられていなかった課題感 • 2017年から開発停止しているGreenDaoがまだ使われている • 時代ごとに違うアーキテクチャ ◦ MVPとMVVMが混ざっている状態 • Kotlin率

    10% • データ操作をすべてまとめる1800行のFatクラス • RxJava部分で頻発する不具合の調査に時間がかかる ◦ 今のメンバーのスキルセットと合っていない技術選定 8 Baby steps to improve architecture In Study Sapuri Android
  9. #sapurimeetup New architecture : to be • データ操作を担当するFatクラス -> DataごとのRepository作成

    • JavaからKotlinへ • MVP → MVVMへ ◦ EventBusからLiveDataへ ◦ RxJavaからCoroutineへ • GreenDao → Room 9 Baby steps to improve architecture In Study Sapuri Android
  10. #sapurimeetup “やっていき”の機運 ビジネス案件が落ち着いた頃 数ヶ月後に大規模な案件が待っていた ➔ “今やるべき案件”として優先度が高まった 10 Baby steps to

    improve architecture In Study Sapuri Android
  11. #sapurimeetup 考慮すべき事項 案件を完全に止めることはできない 数ヶ月後から大規模案件の開発ができるようにしておくこと もちろん大きな障害が出ないように… ➔ 進め方に工夫が必要 11 Baby steps

    to improve architecture In Study Sapuri Android
  12. #sapurimeetup どのように実践するか 02 12 Baby steps to improve architecture In

    Study Sapuri Android
  13. #sapurimeetup New architecture : to be • データ操作を担当するFatクラス -> DataごとのRepository作成

    • JavaからKotlinへ • MVP → MVVMへ ◦ EventBusからLiveDataへ ◦ RxJavaからCoroutineへ • GreenDao → Room 13 Baby steps to improve architecture In Study Sapuri Android
  14. #sapurimeetup 技術選定のポイント • Google公式/推奨のものを基本的に採用 ◦ MVVM, LiveData, Kotlin etc... •

    チームメンバーに馴染みがあるか ◦ RxJavaは難しい… • 学ぶのにモチベーションがあがるか ◦ Kotlin, Coroutine etc... 14 Baby steps to improve architecture In Study Sapuri Android
  15. #sapurimeetup Before 15 … … Fragment.java Activity.java Presenter.java ModelManager.java DB(GreenDao)

    Network EventBusで通知 Baby steps to improve architecture In Study Sapuri Android
  16. #sapurimeetup After 16 … … Fragment.kt Activity.kt ViewModel.kt Repository.kt DB(Room)/Network

    LiveDataで通知 … LiveDataで通知 Baby steps to improve architecture In Study Sapuri Android
  17. #sapurimeetup タスクへの分解 17 Migrate GreenDao to Room - GreenDaoを廃止しRoomを採用 -

    データごとのDaoを作成しモデル層をまとめる Fatク ラスを廃止 アプリ全体 Convert to Kotlin - JavaからKotlinへ変換 各画面 Migrate to MVVM - ViewModelの追加 - EventBusからLiveDataへ変更 - RxJavaからCoroutineへ変更 各画面 Baby steps to improve architecture In Study Sapuri Android
  18. #sapurimeetup ビジネス案件を止めずに改善を行う戦略 18 • タスクを特性によって分解 ◦ 一気に進めないといけないもの ◦ 大規模案件の開発に影響のあるもの ◦

    複数画面に影響のあるもの ◦ 独立して進められるもの • 先にやるもの、後でも問題ないものに分解しスケジュール化 Baby steps to improve architecture In Study Sapuri Android
  19. #sapurimeetup ビジネス案件を止めずに改善を行う戦略 19 • Phase1: Migrate GreenDao to Room ◦

    小さくリリースができないのでまとまった時間を使って進める • Phase2: 大規模案件に影響する画面のKotlin化、MVVM化 ◦ 見通しの良い状態で大規模案件を始めたい • Phase3: その他の画面のKotlin化、MVVM化 ◦ 誰でも独立して進められる。期限の制約がない ◦ MVVM化は最低ViewModelの追加とLiveDataへの導入は行う Baby steps to improve architecture In Study Sapuri Android
  20. #sapurimeetup Try & Error 03 20 Baby steps to improve

    architecture In Study Sapuri Android
  21. #sapurimeetup 試行錯誤した点 21 • スコープの調整 • 新導入したLibraryでのベストプラクティス探し ◦ Kotlin Coroutine

    ◦ LiveData • 開発プロセスの改善 ◦ コードレビュー ◦ タスクのアサインと知見共有 Baby steps to improve architecture In Study Sapuri Android
  22. #sapurimeetup スコープの調整 22 • 一部、改修時の変更に先送りしたこと ◦ RxJavaからCoroutineへ移行 ◦ LiveData経由でローカルのデータを返す Baby

    steps to improve architecture In Study Sapuri Android
  23. #sapurimeetup Kotlin Coroutine 23 • [Before] ExceptionHandlerを使ったエラーハンドリング val scope =

    viewModelScope + CoroutineExceptionHandler { _ , _-> Timber.d("failure clickDebugButton ") } var count = 0 fun clickDebugButton() = scope.launch { count++ if (count % 2 == 0) { throw AssertionError("count%2 is 0") } Timber.d("success clickDebugButton") } ViewModel.kt Baby steps to improve architecture In Study Sapuri Android
  24. #sapurimeetup Kotlin Coroutine 24 期待値は success と failure が交互に出る clickDebugButton:

    success clickDebugButton clickDebugButton: failure clickDebugButton clickDebugButton: success clickDebugButton clickDebugButton: failure clickDebugButton Logcat Baby steps to improve architecture In Study Sapuri Android
  25. #sapurimeetup Kotlin Coroutine 25 実際は一度エラーが出るとcatchし続けてしまう clickDebugButton: success clickDebugButton CoroutineExceptionHandler: failure

    clickDebugButton CoroutineExceptionHandler: failure clickDebugButton CoroutineExceptionHandler: failure clickDebugButton Logcat Baby steps to improve architecture In Study Sapuri Android ※ version 1.2.1
  26. #sapurimeetup Kotlin Coroutine 26 • [After] runCatching, onFailureを使ったハンドリングに変更 var count

    = 0 fun clickDebugButton() = viewModelScope.launch { runCatching { count++ if (count % 2 == 0) { throw AssertionError("count%2 is 0") } }.onSuccess { Timber.d("success clickDebugButton") }.onFailure { Timber.d("failure clickDebugButton") } } ViewModel.kt Baby steps to improve architecture In Study Sapuri Android
  27. #sapurimeetup LiveData 27 [Before] 一つのError fieldに複数の種類のErrorを非同期で通知 private var _errorDebug: MutableLiveData<Error>

    = MutableLiveData() val errorDebug: LiveData<Error> get() = _errorDebug fun clickDebugButton() = viewModelScope.launch(IO) { _errorDebug.postValue(Error.Hoge) } fun clickDebugButton2() = viewModelScope.launch(IO) { _errorDebug.postValue(Error.Fuga) } ViewModel.kt Baby steps to improve architecture In Study Sapuri Android
  28. #sapurimeetup LiveData 28 期待値は Hoge も Fuga も通知してほしい onCreateView: error

    is observed Hoge onCreateView: error is observed Fuga binding.debugButton.setOnClickListener { viewModel.clickDebugButton() viewModel.clickDebugButton2() } Fragment.kt Logcat Baby steps to improve architecture In Study Sapuri Android
  29. #sapurimeetup LiveData 29 実際は Fuga のみ通知される(場合がある) • ほぼ同時に postValue が呼ばれると値が抜ける

    • delay() などでタイミングをズラすと呼ばれる onCreateView: error is observed Fuga Logcat Baby steps to improve architecture In Study Sapuri Android ※ version 2.1.0-alpha02
  30. #sapurimeetup LiveData 30 [After] Error種類によってLiveDataを分けるように変更 fun clickDebugButton() = viewModelScope.launch(IO) {

    _errorHoge.postValue(true) } fun clickDebugButton2() = viewModelScope.launch(IO) { _errorFuga.postValue(true) } ViewModel.kt Baby steps to improve architecture In Study Sapuri Android
  31. #sapurimeetup コードレビュー 31 • Convert to Kotlinのコードレビューがしにくい ◦ 自動変換のものとマニュアルの変更のコミットを分ける •

    細かいコーディングスタイルは進めながら議論 ◦ どの単位でRepositoryを切るか ◦ nonnullにできるところ/lateinit,lazyが使えるところ ◦ スコープ関数何を使うか Baby steps to improve architecture In Study Sapuri Android
  32. #sapurimeetup タスクのアサインと知見共有 32 • DBのマイグレーションなど複数人作業に効率の悪いタスクは専任を決める ◦ 開発途中でブランチを移動するとBuildに時間がかかる • 勉強会を開き知見を共有 ◦

    e.g) Roomの導入 ◦ e.g) RxJavaのコードで起こしやすい不具合の共有 • 特に複雑度の高い画面はペアプロで進める Baby steps to improve architecture In Study Sapuri Android
  33. #sapurimeetup 振り返り・まとめ 03 33 Baby steps to improve architecture In

    Study Sapuri Android
  34. #sapurimeetup 取り組みの結果 34 • Phase1: Migrate GreenDao to Room ◦

    完了 • Phase2: 大規模案件に影響する画面のKotlin化、MVVM化 ◦ 完了 • Phase3: その他の画面のKotlin化、MVVM化 ◦ Kotlin化 49% ◦ MVVM化 44% Baby steps to improve architecture In Study Sapuri Android
  35. #sapurimeetup アーキテクチャ改善は必要か? 35 • Yes. • 当時考えられて作られたアーキテクチャでも開発メンバーも変わればアーキ テクチャの良さも変わる ◦ 開発する自分たちに合うものに変える

    ◦ 自分たちが開発していて気持ちいい環境にする • ドメイン知識の伝承 ◦ 知らない仕様で起きる不具合が多かった Baby steps to improve architecture In Study Sapuri Android
  36. #sapurimeetup ドメイン知識の伝承が役立った場面 36 • 大規模案件の開発のとき ◦ データ構造が複雑に絡み合っている ◦ 複数の条件/状態を前提に開発しなければいけない ◦

    元々不具合がとても多かった画面 Baby steps to improve architecture In Study Sapuri Android
  37. #sapurimeetup 大規模案件を担当したメンバーの声 37 • “正直アーキテクチャ改善でできたところは周辺の部分” • “だけどリファクタでドメイン知識のキャッチアップができたので開発に入りや すかった” Baby steps

    to improve architecture In Study Sapuri Android
  38. #sapurimeetup アーキテクチャ改善が進められた要因 38 • 最新の技術を習得したいDeveloperのモチベーション • ビジネス案件が落ち着いていた • リファクタリングにコストを払う価値がある考えがQuipper全体に浸透してい る

    • 技術選定に関してエンジニアチームに一任されている環境 Baby steps to improve architecture In Study Sapuri Android
  39. #sapurimeetup まとめ • Study Sapuri Androidチームは地道なアーキテクチャ改善を続けてきまし た…!! • リファクタによる恩恵 ◦

    ”複雑な仕様の伝承” ◦ 開発スピード/品質の改善 • 今のアーキテクチャに固執しすぎない、常に良い形を模索していくチーム 39 Baby steps to improve architecture In Study Sapuri Android
  40. #sapurimeetup ご清聴ありがとうございました 40 Baby steps to improve architecture In Study

    Sapuri Android