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
970
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
AWAのフルリニューアルを支えたアーキテクチャ
CA.apk #7
Keita Kagurazaka
March 26, 2019
More Decks by Keita Kagurazaka
See All by Keita Kagurazaka
三者三様 宣言的UI
kkagurazaka
0
530
SELECT FOR UPDATEの話
kkagurazaka
0
500
Mobileアプリのアーキテクチャ設計法
kkagurazaka
2
1.5k
原理から完全理解するDagger Hilt Migration
kkagurazaka
1
2k
今後のJetpackでAndroid開発はこう変わる!
kkagurazaka
16
6.4k
外部SDKのViewにマスク処理をする方法と罠
kkagurazaka
0
1.1k
CQRS Architecture on Android
kkagurazaka
7
3.2k
suspending functionの裏側
kkagurazaka
3
480
coroutinesで非同期ページネーション
kkagurazaka
1
710
Other Decks in Programming
See All in Programming
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
「正の参照」と 「負の導出」で組む ハーネスエンジニアリング
cottpan
1
140
Go1.27で導入されるジェネリクスメソッドでできること
mackee
0
280
フィードバックで育てるAI開発
kotaminato
1
110
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
260
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
230
ローカルLLMでどこまでコードが書けるか -縮小版 / How much code can be written on a local LLM Shortened
kishida
2
190
AIを活用したE2Eテスト実装効率化のあゆみ / ebisu-mobile-14-kotetu
kotetuco
0
170
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
160
LaravelLive Japan の裏方のすべて — 第188回 PHP勉強会@東京 (2026-06-24)
suguruooki
2
150
Honoでのサプライチェーン侵害対策 〜 3つのライブラリに学ぶ
yusukebe
7
1.8k
The Bowling Game- From Imperative to Functional Programming - Part 1
philipschwarz
PRO
0
310
Featured
See All Featured
Building Adaptive Systems
keathley
44
3.1k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
220
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
340
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.8k
Side Projects
sachag
455
43k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
170
GraphQLとの向き合い方2022年版
quramy
50
15k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.7k
SEO for Brand Visibility & Recognition
aleyda
0
4.6k
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!