Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Immutable data holder
Search
haru067
February 28, 2019
Technology
1.4k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Immutable data holder
haru067
February 28, 2019
More Decks by haru067
See All by haru067
Jetpack Compose: 効果的なComposable関数のAPI設計
haru067
2
8.4k
いかにしてアプリの起動時間を改善するか
haru067
3
2.3k
REALITY Androidにおけるマルチモジュール移行
haru067
0
1.4k
ARTのメモリ管理
haru067
8
16k
Other Decks in Technology
See All in Technology
AI AgentによるEmbedded SREの取り組み
tgidgd
1
360
AI Agent 時代のデータ基盤: ClickHouse で実現する 超高速分析とコスト削減の両立
jozono
0
200
お客様の「やりたい」の先を見通す合意形成プロセス ~裏にある課題と不安を解きほぐすコツ~
yukakoseki
0
110
AI時代の組織作り:チーム開発から「個人×AI」への移行と、持続可能な「開発資本」の築き方
ham0215
2
300
Copilot Coworkで「みのるん式」やってみた
minorun365
PRO
2
1.6k
Metadata - Section 3 : Dublin Core Standard · DC
mohab1
0
110
AX時代の自治体支援リソース再配分と役割分担の再構成:戦略とロードマップ(概要)
sishi2026
0
200
セキュリティ専任チームなしで攻撃を先回りするSREが実践したSIEM on Amazon OpenSearch Service
cscengineer
PRO
0
560
[General] 개발자로 해외 기업에서 일하기
skydoves
1
310
企画からFlutter実装まで、1つの機能を一貫して開発したプロセスと成果物
khiroyuki1003
1
160
AI時代のエンジニアの情報発信〜個人の発信を組織の力に変える〜
ryo_kawamata
1
7.4k
増え続けるプロダクトの品質をどう担保するか。ProductSpecとTypeScriptによる取り組み
joere
3
1k
Featured
See All Featured
Test your architecture with Archunit
thirion
2
2.5k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
22k
Exploring anti-patterns in Rails
aemeredith
4
560
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.7k
Ethics towards AI in product and experience design
skipperchong
2
460
Speed Design
sergeychernyshev
33
2.2k
30 Presentation Tips
portentint
PRO
1
460
What does AI have to do with Human Rights?
axbom
PRO
1
2.5k
Visualization
eitanlees
153
17k
A better future with KSS
kneath
240
18k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
33
5.6k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
660
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 ΑΓ