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
Immutable data holder
Search
haru067
February 28, 2019
Technology
1
1.3k
Immutable data holder
haru067
February 28, 2019
Tweet
Share
More Decks by haru067
See All by haru067
Jetpack Compose: 効果的なComposable関数のAPI設計
haru067
2
7.3k
いかにしてアプリの起動時間を改善するか
haru067
3
2.1k
REALITY Androidにおけるマルチモジュール移行
haru067
0
1.4k
ARTのメモリ管理
haru067
8
15k
Other Decks in Technology
See All in Technology
AI Agentと MCP Serverで実現する iOSアプリの 自動テスト作成の効率化
spiderplus_cb
0
490
社内お問い合わせBotの仕組みと学び
nish01
0
180
o11yで育てる、強い内製開発組織
_awache
3
120
From Prompt to Product @ How to Web 2025, Bucharest, Romania
janwerner
0
120
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
9k
AIが書いたコードをAIが検証する!自律的なモバイルアプリ開発の実現
henteko
1
340
PLaMoの事後学習を支える技術 / PFN LLMセミナー
pfn
PRO
9
3.8k
許しとアジャイル
jnuank
1
120
How to achieve interoperable digital identity across Asian countries
fujie
0
110
生成AIを活用したZennの取り組み事例
ryosukeigarashi
0
200
stupid jj tricks
indirect
0
7.9k
英語は話せません!それでも海外チームと信頼関係を作るため、対話を重ねた2ヶ月間のまなび
niioka_97
0
110
Featured
See All Featured
How to Ace a Technical Interview
jacobian
280
24k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
140
34k
Done Done
chrislema
185
16k
Building Flexible Design Systems
yeseniaperezcruz
329
39k
jQuery: Nuts, Bolts and Bling
dougneiner
64
7.9k
Git: the NoSQL Database
bkeepers
PRO
431
66k
Six Lessons from altMBA
skipperchong
28
4k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
32
2.2k
How to Think Like a Performance Engineer
csswizardry
27
2k
Imperfection Machines: The Place of Print at Facebook
scottboms
269
13k
Visualization
eitanlees
148
16k
4 Signs Your Business is Dying
shpigford
185
22k
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 ΑΓ