์์ฆ์ compose๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ ์ถ์ธ์ด๋ค. ํ์๋ compose๋ฅผ ๋ง์ด ์ฌ์ฉํ๊ณ ์๋ค.
ํ์๊ฐ ์ง์ธ๋ค์๊ฒ compose์ mvi๋ฅผ ์ฌ์ฉํ๋ฉด ์ข๋ค๋ ์์์ ๋ฃ๊ณ ๋ฐ๋ก mvi ๊ณต๋ถ๋ฅผ ์์ํ๋ค.
์ง๊ธ ๋ฐ๋ก mvi์ ๋ํด ์์๋ณด์.
1. mvi๋?
mvi ์ํคํ ์ฒ๋ mvc, mvp, mvvm์ ๊ฐ์ ์๋๋ก์ด๋ ๊ฐ๋ฐ์๋ค์ ๊ฐ๋ฐ๊ณผ ์ ์ง ๋ณด์๋ฅผ ํธ๋ฆฌํ๊ฒ ํด์ฃผ๋ ์ํคํ ์ฒ ํจํด์ ์ผ์ข ์ด๋ผ ํ ์ ์๋ค.
mvi์ ๊ตฌ์กฐ๋ model - view - intent๋ก ๊ตฌ์ฑ๋๋ฉฐ ๊ฐ layer๋ ์๋ก ์์ ํ ๊ด์ฌ์ฌ๊ฐ ๋ถ๋ฆฌ๋์ด ์๋ค.
sideEffects๋ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ์์ (api ํต์ , ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋์์ ์ฒ๋ฆฌํ ๋ก์ง)๊ณผ ์ธ์คํด์ค ๋ทฐ(screen ๊ฐ ์ด๋, toast์ dialog)๋ฑ์ ์ฒ๋ฆฌํ๋ค.
sideEffects๊ฐ ์์ผ๋ฉด ์ฌ์ฉ์์ ํ์์ ๋ฐ๋ผ sideEffects์ ๋ก์ง์ด ์ํ๋ ๊ฒ์ด๋ค.
2. mvi๋ฅผ ์ฌ์ฉํ๋ ์ด์ ?
์ด๊ฒ ์ฌ์ค ๋ณธ๋ก ์ด๋ค "์ด ํจํด์ ์ ์ฌ์ฉํด์ผ ํ๋๊ฐ?"์ด๋ค.
mvi๋ฅผ ์ ์ฌ์ฉํด์ผ ํ๋๋ฉด
์ฐ๋ฆฌ๊ฐ ๋ง๋๋ ์๋๋ก์ด๋ ์ฑ์ ์ฌ์ค state(์ํ)์ ์งํฉ์ด๋ค.
์๋๋ก์ด๋ ์ฑ์์๋ ๋ค์ํ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์์ผ state๋ฅผ ์์ฑํด ๋ธ๋ค.
์๋ฅผ ๋ค์ด button์ ํด๋ฆญํ๋ค ๋๋ api ํธ์ถ ํ ์ฑ๊ณต/์คํจ ์ ๊ฐ์ ๊ฒฝ์ฐ๊ฐ ์๋ค.
์๋๋ก์ด๋ ๊ฐ๋ฐ์๋ค์ ๋ชจ๋ ์ด state๋ค์ ๊ด๋ฆฌํ๋ฉด์ ์ฑ์ ๋ง๋ค์ด์ผ ํ๋ค.
๋ง์ฝ state์ ๊ด๋ฆฌ๊ฐ ์ ๋๋ก ์ด๋ฃจ์ด์ง์ง ์๋๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
์์ ์ฌ์ง์ api ํต์ ์ผ๋ก ๊ตญ๊ฐ์ ์ ๋ณด์ image๊ฐ ์ ์์ ์ผ๋ก ์ถ๋ ฅ๋์๋๋ฐ(success ์ํ)
๋ก๋ฉ indicator๊ฐ ์ฌ๋ผ์ง์ง ์๊ณ ์๋ค.(loading ์ํ)
์ฐ๋ฆฌ๋ค์ ์์ ๊ฐ์ ๋ฌธ์ ๋ค์ ์ฌ์ ์ ๋ง์ผ๋ฉด์, ์๋ง์ ์ํ๋ค์ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ ์ํด mvi๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค!
3. mvi ์ฌ์ฉ๋ฒ(?)
mvi๊ฐ ์ ํ์ํ์ง ์์์ผ๋ฉด ์ด์ ๋ ์ฌ์ฉ๋ฒ(?)์ ์ตํ๋ณด์.
1. model
model์์ screen์ ์ฌ์ฉํ state๋ค์ ์์ฑํ๋ค.
์๋ฅผ ๋ค์ด success ์ํ, fail ์ํ, loading ์ํ, ๋ฐ์ดํฐ ์ ๋ณด(api ์ ๋ณด ๋ฑ๋ฑ..)๋ฅผ ์ถ๊ฐํ ์ ์๋ค.
data class MainState(
val onLoading: Boolean = false,
val onComplete: Boolean = false,
val onFail: Boolean = false,
val apiData: ApiData? = null
)
์์ ๋ฅผ ๋ณด๋ฉด loading, complete, fail ์ํ์ state์ api data๊ฐ ์ถ๊ฐ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
2. intent
intent์์๋ state์ ๋ฐ๋ฅธ event๋ค์ ์ ์ํ๋ค.
intent๋ฅผ ๊ตฌํํ๋ ๊ฒ์ sealed class๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅํ๋ค๊ณ ํ๋ค.
๊ฐ๋ฐ์๋ ์์ ์ด ์์ฑํ state์ ๋ฐ๋ฅธ event๋ฅผ ์์ฑํด์ ํธ์ถ์ํฌ ์ ์๋ค.
sealed class MainIntent {
data class apiData(apiData: ApiData): MainIntent()
object OnError: MainIntent()
}
์์ ์์ ์์๋ api๊ฐ ํธ์ถ๋์์ ๋์ ์ด๋ฒคํธ์
error์ ์ด๋ฒคํธ๋ฅผ ์์ฑํ์๋ค.
intent๋ ํ ํ๋ฉด์์ ์ผ์ด๋๋ state event๋ฅผ ๊ด๋ฆฌํ ์ ์๋ค.
3. sideEffects
sideEffects์์๋ ์์์๋ ์ธ๊ธํ๋ค์ํผ, intent์์ ํ๊ธฐ์๋ ์ด๋ ค์ด ์์ ๋ค(api ๋ก์ง, ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋์์ ํ ์์ , ์ธ์คํด์ค ๋ทฐ ๋ฑ)์ ์ ์ํ๋ค.
sealed class MainSideEffects {
data class ApiRequest(requestBoody: RequestBody): MainSideEffects()
}
4. view
view๋ intent์์ ์์ฑํ state(์ํ)์ ๋ฐ๋ฅธ event๋ฅผ ์ด์ฉํด ํ๋ฉด์ ๊ตฌ์ฑํ๋ ์ญํ ์ ํ๋ค.
compose์ ๊ฒฝ์ฐ์๋ ์์ง ์ ๋ชจ๋ฅด๊ฒ ์ง๋ง xml์ ๊ฒฝ์ฐ์๋ databinding์ด ์ฌ์ฉ๋๋ค๊ณ ์๊ณ ์๋ค.
๊ฐ๋จ ์ ๋ฆฌ
- mvi๋ ์๋๋ก์ด๋ ์ฑ์ state(์ํ) ๊ด๋ฆฌ์ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋ ์ํคํ ์ฒ ํจํด์ด๋ค.
- mvi๋ฅผ ๋ฐฐ์ฐ๊ธฐ ์ํด ์์์ผ ํ ์ฌ์ ์ง์์ด ๋ง์ ๊ฒ ๊ฐ๋ค.
- ๋ํ ํ ํ๋ฉด์ ๋ชจ๋ ์ํ๋ฅผ ์์ฑํ์ฌ์ผ ํ๊ธฐ์ ๊ฐ๋จํ state ๋ณํ๋ ๋ชจ๋ ์ฝ๋๋ก ์ ์ด ์ฃผ์ด์ผ ํ๋ค.
์ ๋ฆฌ
- mvi์ ๋ํด ๊ณต๋ถํด ๋ณด์๋๋ฐ ์์ง ๋ถ์กฑํ ์ ์ด ๋ง์๋ค.
- mvi๋ ๋จ์ ๋ ์์ง๋ง state ๊ด๋ฆฌ๊ฐ ์ค์ํ compose์ ๊ฐ์ด ์ฌ์ฉํ๋ฉด ์ต๊ณ ์ ์๋์ง๊ฐ ๋ ๊ฒ ๊ฐ๋ค.
- ์ด์ ์ง์ ์ค์ ์์ ์ฌ์ฉํ๋ฉด์ ๊ณต๋ถํ ๋ด์ฉ์ ์ ์ฉํ๊ณ ์ถ์ด์ก๋ค.
- ๋ค๋ฅธ mv ์๋ฆฌ์ฆ์๋ ๋ค๋ฅด๊ฒ ๋ช ํํ ์ฅ์ ์ด ์๋ ์ํคํ ์ฒ ํจํด ๊ฐ์๋ค(๊ธฐ๋ถ ํ์ผ ์๋ ์๋ค.)
์ ์์ค ์ฝ๋๋ ์๋์ ์ต์ฌํธ ๊ฐ์ฌ๋์ ๊ฐ์๋ฅผ ์ฌ์ฉํด ์ ์ ๋ง๋๋ก(?) ์กฐ๊ธ์ฉ ๋ฐ๊พธ์์ต๋๋ค. ์ค๋ฅ๊ฐ ์์ ์๋ ์์ผ๋ ์ํด ๋ฐ๋๋๋ค. ์์ธํ ๋ด์ฉ์ ๊ฐ์ฌ๋์ ๊ฐ์๋ฅผ ์ฐธ๊ณ ํด ๋ณด์๋ฉด ๋์์ด ๋ ๊ฒ ๊ฐ์ต๋๋ค :0
์ฐธ๊ณ