Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Immutable data holder
haru067
February 28, 2019
Technology
1
880
Immutable data holder
haru067
February 28, 2019
Tweet
Share
More Decks by haru067
See All by haru067
いかにしてアプリの起動時間を改善するか
haru067
2
960
REALITY Androidにおけるマルチモジュール移行
haru067
0
1k
ARTのメモリ管理
haru067
7
14k
Other Decks in Technology
See All in Technology
成長を続ける組織でのSRE戦略:プレモーテムによる信頼性の認識共有 SRE Next 2022
niwatakeru
7
1.7k
Power BIのモバイルと都 +1 / Tokyo
ishiayaya
0
120
Power BI Premiumでデータ準備!
hanaseleb
1
170
jaws-ug-asa-datasync-20220510
hiashisan
0
430
Salesforce女子部-権限についてまとめてみたその1
sfggjp
0
130
Power BI Report Ops
hanaseleb
0
140
mROS 2のススメ
takasehideki
0
280
AWS全体のセキュリティ管理と快適なセキュリティ運用
cmusudakeisuke
2
10k
僕の Microsoft Teams (+α) 便利技紹介 2022年春
taichinakamura
0
1.7k
CLI専門支部に参加したら AWSエンジニアに転職できた件について
tsukuboshi
0
610
Babylon.js で簡単 WebXR
yuhara0928
1
270
5分で完全理解するGoのiota
uji
3
1.3k
Featured
See All Featured
What’s in a name? Adding method to the madness
productmarketing
11
1.5k
The Brand Is Dead. Long Live the Brand.
mthomps
45
2.7k
4 Signs Your Business is Dying
shpigford
169
20k
The Invisible Customer
myddelton
110
11k
Teambox: Starting and Learning
jrom
121
7.6k
Code Reviewing Like a Champion
maltzj
506
37k
Bootstrapping a Software Product
garrettdimon
294
110k
Three Pipe Problems
jasonvnalue
89
8.6k
Designing on Purpose - Digital PM Summit 2013
jponch
106
5.6k
Side Projects
sachag
449
37k
Making the Leap to Tech Lead
cromwellryan
113
6.9k
Agile that works and the tools we love
rasmusluckow
319
19k
Transcript
Immutable data holder 2019/02/28 potatotips #59
よくある話 タップしてユーザのプロフィールを表示 λοϓ
MVVMによる実装 • ユーザIDを引数としてViewModelがRepository からfetch • pro leはDataBindingを通じてViewに表示 fun load(userId: String)
= profileRepository.fetchProfile(userId) { profile.value = it } ProfileViewModel.kt
MVVMによる実装 • ユーザIDを引数としてViewModelがRepository からfetch • pro leはDataBindingを通じてViewに表示 fun load(userId: String)
= profileRepository.fetchProfile(userId) { profile.value = it } ProfileViewModel.kt
MVVMによる実装 • ユーザIDを引数としてViewModelがRepository からfetch • pro leはDataBindingを通じてViewに表示 fun load(userId: String)
= profileRepository.fetchProfile(userId) { profile.value = it } ProfileViewModel.kt var profile = MutableLiveData<Profile>()
MVVMによる実装 • ユーザIDを引数としてViewModelがRepository からfetch • pro leはDataBindingを通じてViewに表示 fun load(userId: String)
= profileRepository.fetchProfile(userId) { profile.value = it } ProfileViewModel.kt var profile = MutableLiveData<Profile>()
MVVMによる実装 • ユーザIDを引数としてViewModelがRepository からfetch • pro leはDataBindingを通じてViewに表示 fun load(userId: String)
= profileRepository.fetchProfile(userId) { profile.value = it } ProfileViewModel.kt var profile = MutableLiveData<Profile>() ͳΜͱ͔͠ͳ͍ͱɾɾɾɾ
Lv1: mutableな変数宣言をやめる 知らないうちにobserveできなくなってしまう val に書き換えでimmutableに var data = MutableLiveData<String>() data.observe(this,
Observer { print(it) }) data.value = "hello" data = MutableLiveData() data.value = "world" // ͜͜observe͞Εͳ͍ var profile = MutableLiveData<Profile>() val profile = MutableLiveData<Profile>()
Lv2: mutableなデータを公開しない 変数をvalにしてもオブジェクト自体はまだmutable ViewがViewModelのデータを変更できてしまう 外からはread onlyなデータだけが見える形にする val data =
MutableLiveData<String>() data.value = "hello" data.value = "world" // いくらでも更新できる private val _profile: MutableLiveData<Profile>() val profile: LiveData<Profile> get() = _profile val profile = MutableLiveData<Profile>()
良さそう? まあよさそう。だが、、 privateとはいえViewModel内なら書き換え可能 • ViewModelが肥大化したら多分事故る •
そもそも2つも変数を宣言するのはくどい private val _profile: MutableLiveData<Profile>() val profile: LiveData<Profile> get() = _profile ProfileViewModel.kt
Lv3: そもそもmutableにしない switchMapを使いimmutableな定義に private val _userId = MutableLiveData<String>() … val
profile: LiveData<Profile> = Transformations.switchMap(_userId){ profileRepository.getProfile(it) }
Lv3: そもそもmutableにしない switchMapを使いimmutableな定義に private val _userId = MutableLiveData<String>() … val
profile: LiveData<Profile> = Transformations.switchMap(_userId){ profileRepository.getProfile(it) } userIdの変更を監視
Lv3: そもそもmutableにしない switchMapを使いimmutableな定義に private val _userId = MutableLiveData<String>() … val
profile: LiveData<Profile> = Transformations.switchMap(_userId){ profileRepository.getProfile(it) } IDに変更があればfetch
Lv3: そもそもmutableにしない switchMapを使いimmutableな定義に private val _userId = MutableLiveData<String>() … val
profile: LiveData<Profile> = Transformations.switchMap(_userId){ profileRepository.getProfile(it) }
Lv3: そもそもmutableにしない switchMapを使いimmutableな定義に • 「pro leはIDの更新以外を理由に変更できない」 という制約をコード上で表現することができる • 「pro
leはIDをトリガーとしてfetchした値」 というデータのフローが明確になる private val _userId = MutableLiveData<String>() … val profile: LiveData<Profile> = Transformations.switchMap(_userId){ profileRepository.getProfile(it) }
まとめ mutable、やめよう • 変数宣言 • オブジェクトが抱えるデータ LiveDataならswitchMap(Transformations) を使うといい感じに
Bonus: より簡潔に 拡張関数を活用すると良さそう(ktxにある?) Transformations.switchMap(_userId) { profileRepository.getProfile(it) } _userId.switchMap
{ profileRepository.getProfile(it) } fun <X, Y> LiveData<X>.switchMap(body: (X) -> LiveData<Y>): LiveData<Y> { return Transformations.switchMap(this, body) } 長い シンプル https://github.com/google/iosched ͷ Extensions.kt ΑΓ