Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
AWAのフルリニューアルを支えたアーキテクチャ
Search
Keita Kagurazaka
March 26, 2019
Programming
1
800
AWAのフルリニューアルを支えたアーキテクチャ
CA.apk #7
Keita Kagurazaka
March 26, 2019
Tweet
Share
More Decks by Keita Kagurazaka
See All by Keita Kagurazaka
SELECT FOR UPDATEの話
kkagurazaka
0
250
Mobileアプリのアーキテクチャ設計法
kkagurazaka
2
1.3k
原理から完全理解するDagger Hilt Migration
kkagurazaka
1
1.7k
今後のJetpackでAndroid開発はこう変わる!
kkagurazaka
16
5.9k
外部SDKのViewにマスク処理をする方法と罠
kkagurazaka
0
860
CQRS Architecture on Android
kkagurazaka
7
2.8k
suspending functionの裏側
kkagurazaka
3
420
coroutinesで非同期ページネーション
kkagurazaka
1
600
async/awaitで快適非同期ライフ
kkagurazaka
4
1.8k
Other Decks in Programming
See All in Programming
Macとオーディオ再生 2024/11/02
yusukeito
0
370
Quine, Polyglot, 良いコード
qnighy
4
640
リアーキテクチャxDDD 1年間の取り組みと進化
hsawaji
1
220
C++でシェーダを書く
fadis
6
4.1k
型付き API リクエストを実現するいくつかの手法とその選択 / Typed API Request
euxn23
8
2.2k
初めてDefinitelyTypedにPRを出した話
syumai
0
410
카카오페이는 어떻게 수천만 결제를 처리할까? 우아한 결제 분산락 노하우
kakao
PRO
0
110
AWS Lambdaから始まった Serverlessの「熱」とキャリアパス / It started with AWS Lambda Serverless “fever” and career path
seike460
PRO
1
260
Amazon Bedrock Agentsを用いてアプリ開発してみた!
har1101
0
330
最新TCAキャッチアップ
0si43
0
140
as(型アサーション)を書く前にできること
marokanatani
10
2.6k
ピラミッド、アイスクリームコーン、SMURF: 自動テストの最適バランスを求めて / Pyramid Ice-Cream-Cone and SMURF
twada
PRO
10
1.3k
Featured
See All Featured
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
0
89
Large-scale JavaScript Application Architecture
addyosmani
510
110k
The Invisible Side of Design
smashingmag
298
50k
Keith and Marios Guide to Fast Websites
keithpitt
409
22k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
Being A Developer After 40
akosma
86
590k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.8k
Become a Pro
speakerdeck
PRO
25
5k
RailsConf 2023
tenderlove
29
900
A Tale of Four Properties
chriscoyier
156
23k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Transcript
AWAの フルリニューアルを支えた アーキテクチャ 2019/03/26 CA.apk #7 Keita Kagurazaka
AWAについて • 定額制音楽ストリーミングサービス • 競合にはSpotify, Apple Music, YouTube Music, LINE
MUSICなどなど • Androidアプリは2019年1月24日にフルリ ニューアルをリリース
なぜリニューアルしたのか • リリースしてから3年以上にわたって機能を付け足し続けた結 果、複雑でユーザの理解が難しいプロダクトに ◦ アプリを初めて使ったユーザが何をすればいいかわからない • 開発速度を優先した結果、メンテナンスが困難なソフトウェア に ◦
Fat Activity、上げられないライブラリのバージョン、作成時代によって 違う設計 etc.
リニューアルの目的 • すべての機能を再整理し、新規ユーザでもわかりやすいUIに 変更、UXを最大化する • これまで溜め込んだ技術的負債を返済し、今後の開発速度を 向上させる
リアーキテクチャ
そもそもアーキテクチャって なんのためにあるの?
アーキテクチャは何のためにあるか • すべてのアーキテクチャは本質的には制約 • 開発者ができることを減らすことで、誤りを防ぐ • 間違えないなら制約は緩くてよい
アーキテクチャは何のためにあるか • すべてのアーキテクチャは本質的には制約 • 開発者ができることを減らすことで、誤りを防ぐ • 間違えないなら制約は緩くてよい どのくらい自由度を犠牲にすべきかは チームとプロダクトに強く依存する
チームとアーキテクチャ (1) • チームの人数が多ければ多いほど、自由度は制限したほうが 良い ◦ コミュニケーションコストは人数に対して指数関数的に増加する ◦ 小チームに分けるという選択肢は有力 ◦
採用も見据えて考える
チームとアーキテクチャ (2) • 技術習得度が高くないメンバーが含まれる場合、自由度は制 限したほうが良い ◦ 設計方針を事前レビューしてから実装してもらうくらいなら最初から枠 組みがあったほうが良い ◦ 技術習得度が高いメンバーとペア
/ モブプログラミングをする場合は 自由度を高くできる
プロダクトとアーキテクチャ • プロダクトが巨大で複雑な場合、自由度は制限したほうが良 い ◦ 人数の話と基本的には同じ ◦ 機能で分割するのは有力 (Androidならばmulti-module) ◦
ドメインの複雑さは向き合うしかない
AWAのAndroidチームとアーキテクチャ • チームは4人と小規模 • 技術習得度は全員高く、必要な議論を躊躇わないタイプ • プロダクトは巨大で複雑 (167画面とかある) • 拠点が渋谷と福岡で分かれている
設計方針 • レイヤードアーキテクチャを採用し、各処理をどの階層に置く かまで合意する • ルール化したほうが良さそうならば都度議論する • 重要度が高く、複雑な音楽再生とダウンロードについてはより 制約をきつくする •
必要なら福岡にいく
設計方針 • レイヤードアーキテクチャを採用し、各処理をどの階層に置く かまで合意する • ルール化したほうが良さそうならば都度議論する • 重要度が高く、複雑な音楽再生とダウンロードについてはより 制約をきつくする •
必要なら福岡にいく ビデオ通話を常時接続する
方針は定まった
実現したいこと • ユーザに対してローディング表示をなるべく見せないようにす るため、キャッシュを最大限に活用する • 音楽が再生できる画面では再生状況をリアクティブに表示した い
実現したいこと • ユーザに対してローディング表示をなるべく見せないようにす るため、キャッシュを最大限に活用する • 音楽が再生できる画面では再生状況をリアクティブに表示した い CQRSアーキテクチャを採用
CQRS (コマンドクエリ責務分離) • システム全体を更新系と参照系に分離する • 更新系の操作は値を返さない • 参照系はシステムを更新しない (副作用なし) •
詳しくはこちら https://speakerdeck.com/kkagurazaka/cqrs-architecture-on-android
更新系 View ViewModel UseCase ApiClient DB Data Command ApiClient Repository
Data Command ワーカースレッドで実行
更新系 View ViewModel UseCase ApiClient DB Data Command ApiClient Repository
Data Command • Viewからのイベントを受けてUseCaseをキック する
更新系 View ViewModel UseCase ApiClient DB Data Command ApiClient Repository
Data Command • DataCommandをオーケストレーションして処 理を行う • 戻り値はCompletable
更新系 View ViewModel UseCase ApiClient DB Data Command ApiClient Repository
Data Command • APIからデータを取得してDBに書き込む • 扱うEntityごとにクラスが分かれる • 戻り値はCompletable
更新系 View ViewModel UseCase ApiClient DB Data Command ApiClient Repository
Data Command • Entityを保存するだけ • トランザクションを管理する • 戻り値はUnit
更新系 View ViewModel UseCase ApiClient DB Data Command ApiClient Repository
Data Command • 消えてもいいキャッシュはRealm • 重要なデータはSQLite (Room) • 設定系はSharedPreferences • プロセスを跨がせないデータはon-memory
参照系 View ViewModel UseCase DB Data Query Repository Data Query
RealmのためにUIスレッドで実行 Repository
参照系 View ViewModel UseCase DB Data Query Repository Data Query
Repository • DBの変更を検知してRxJavaのストリームに変 換する • 戻り値はFlowable<Entity> • Realmの場合はRealmResults<Entity>
参照系 View ViewModel UseCase DB Data Query Repository Data Query
Repository • 必要があればEntityを分解した値にしたり、 distinctUntilChangedしたり • ごく一部のキャッシュしない参照のためにAPIを 叩くこともある
参照系 View ViewModel UseCase DB Data Query Repository Data Query
Repository • DataQueryをオーケストレーションして、Viewに 必要な情報を作る
参照系 View ViewModel UseCase DB Data Query Repository Data Query
Repository • UseCaseをobserveしてObservableFieldに詰 め、DataBindingでViewをリアクティブに更新 する
実現したいこと (再掲) • ユーザに対してローディング表示をなるべく見せないようにす るため、キャッシュを最大限に活用する • 音楽が再生できる画面では再生状況をリアクティブに表示した い
実現したいこと (再掲) • ユーザに対してローディング表示をなるべく見せないようにす るため、キャッシュを最大限に活用する • 音楽が再生できる画面では再生状況をリアクティブに表示した い キャッシュを書いてから画面に表示する作り バックグラウンドでデータが書き換わると画面もリアクティブに
変化する
制限を緩めたところ • 本来CQRSでは更新系と参照系でEntityのクラスを分けるが、 重要度が高い再生キューとダウンロード以外は分けなかった ◦ 参照系で更新操作をしないようにしよう、で事足りた • 細かいコーディング規約は定めず、コミット前にコードフォー マットすることだけにした ◦
たとえばapply派とalso派が混在しているが別に問題はなかった
実際やってみてどうだったか
リアーキテクチャしてみて • どこに何を書いたら良いか迷わなくなった • 責務が分かれたため、テストが書きやすくなった • データフローがわかりやすくなったことによってメンテナンス性 が向上した • パフォーマンスには注意
まとめ • AndroidアプリをCQRSアーキテクチャでフルリニューアルした • 不具合をほとんど出さずにすばやく開発できるようになった • ベストなアーキテクチャはチームとプロダクトによって違う
Thanks!