
fromm ์ฑํ ๋ฆฌ๋ด์ผ: MVI ๋์ ๋ฐ ์ฑ๋ฅ ๊ฐ์

- #Android
- #MVI
- #MVVM
๋ค์ด๊ฐ๋ฉฐ
์๋ ํ์ธ์. ๋ ธ๋จธ์ค ๋ชจ๋ฐ์ผํ์์ ์๋๋ก์ด๋ ๊ฐ๋ฐ์ ๋งก๊ณ ์๋ ์ค์์์ ๋๋ค. ์ ํฌ ํ์ฌ์์ ์ด์ํ๋ fromm ์ฑ์ ์ํฐ์คํธ์ ํฌ์ด ์ํตํ๋ ํ๋ซํผ์ผ๋ก, ์ฑํ ๊ธฐ๋ฅ์ด ์๋น์ค์ ์ค์ฌ์ ์ธ ์ญํ ์ ํฉ๋๋ค. ํ์ง๋ง ์ถ์ ์ด๊ธฐ, 4๊ฐ์์ด๋ผ๋ ์งง์ ๊ฐ๋ฐ ๊ธฐ๊ฐ ๋ด์ ๋น ๋ฅด๊ฒ ์ฑ์ ์์ฑํ๋ค๋ณด๋ ์ฑ๋ฅ์ด๋ ํ์ฅ์ฑ, ์ ์ง๋ณด์์ฑ ๋ฑ์ ์ถฉ๋ถํ ๊ณ ๋ คํ์ง ๋ชปํ๋ ์์ฌ์์ด ์์์ต๋๋ค.
์ด์ ๋ฐ๋ผ 2024๋ ํ๋ฐ๊ธฐ์๋ ๊ธฐ์กด ๊ตฌ์กฐ์ ๋ณต์ก์ฑ์ ๊ฐ์ ํ๊ณ ์ง์์ ์ธ ๊ธฐ๋ฅ ํ์ฅ๊ณผ ์ํํ ์ ์ง๋ณด์๋ฅผ ์ํด ์ฑํ ์์คํ ์ ๊ทผ๋ณธ์ ์ธ ๊ฐ์ ์์ ์ ์งํํ๊ฒ ๋์์ต๋๋ค. ์๋ฒ API ๋ณ๊ฒฝ๋ฟ๋ง ์๋๋ผ ์๋๋ก์ด๋ ์ฑ์ ์ ์ฒด์ ์ธ ์ํคํ ์ฒ ๋ณ๊ฒฝ, ๋ชจ๋ UI๋ฅผ Jetpack Compose๋ก ์ฌ๊ตฌ์ฑํ๋ ๋ฑ ๋ง์ ๋ณํ๊ฐ ์์์ต๋๋ค. ์ด๋ฒ ๊ธ์์๋ ์ด๋ฌํ ๋๊ท๋ชจ ๊ฐ์ ์์ ์ค์์๋, ํนํ ๊ธฐ์กด ํ๋ก์ ํธ์ ์ฑํ ๋ฐฉ ๋ฉ์์ง ๊ด๋ฆฌ ๋ฐฉ์์์์ ๊ตฌ์กฐ์ , ์ฑ๋ฅ์ ๋ฌธ์ ๋ค์ ์ด๋ป๊ฒ ํด๊ฒฐํ๋์ง์ ๋ํด ์๊ฐํด๋ณด๊ณ ์ ํฉ๋๋ค.
๊ธฐ์กด ์ฑํ ์์คํ ์ ๊ตฌ์กฐ์ ๋ฌธ์ ์ ๊ณผ ์ฑ๋ฅ ์ ํ
1. God Class ๋ฌธ์ : ChatManager์ ๊ณผ๋ํ ์ฑ ์
๊ธฐ์กด ์ฑํ ์์คํ ์์์ ๊ฐ์ฅ ํฐ ๋ฌธ์ ๋ ChatManager๋ผ๋ ๊ฑฐ๋ํ Singleton ๊ฐ์ฒด์์ต๋๋ค.
ChatManager๋ ๋ค์๊ณผ ๊ฐ์ ๋ค์ํ ์ญํ ์ ๋งก๊ณ ์์์ต๋๋ค.
- ์ฑํ ๋ฐฉ ๋ชฉ๋ก ๊ด๋ฆฌ
- ๋ชจ๋ ์ฑํ ๋ฐฉ์ ๋ฉ์์ง ๋ก๋
- ์์ ๋ ๋ฉ์์ง ์ ๋ฐ์ดํธ
- ๋ฉ์์ง ์ญ์ ๋ฐ ์จ๊น ์ฒ๋ฆฌ
- ๋ฒ์ญ ๊ธฐ๋ฅ ๊ด๋ฆฌ
- ์ฑํ ์ฐ๊ฒฐ ๋ฐ ํด์ ๊ด๋ฆฌ
์ด์ฒ๋ผ ChatManager๋ ์ฑํ ๊ณผ ๊ด๋ จ๋ ๊ฑฐ์ ๋ชจ๋ ๋ก์ง์ ๊ด๋ฆฌํ์ต๋๋ค. ๋ฌธ์ ๋ ChatManager๊ฐ Singleton ๊ฐ์ฒด๋ก ๊ตฌํ๋์ด ์ ์ญ์ ์ผ๋ก ์ ๊ทผ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์, ์ฝ๋ ๊ณณ๊ณณ์์ ChatManager์ ์์กดํ๊ฒ ๋์๋ค๋ ์ ์ ๋๋ค. ์ด๋ ChatManager์ ์ฑ ์์ด ๋์ฑ ๋น๋ํด์ง๋ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ์ต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก, ChatManager๋ โGod Classโ๊ฐ ๋์ด, ์์ ๋ณ๊ฒฝ์๋ ์ ์ฒด ์์คํ ์ ์ํฅ์ ๋ฏธ์น ์ ์๋ ์ํ์ ๋ดํฌํ๊ฒ ๋์์ต๋๋ค. ๋ํ, ๊ฐ ์ญํ ์ด ๋ ๋ฆฝ์ ์ผ๋ก ๊ด๋ฆฌ๋์ง ๋ชปํ๊ณ ChatManager์ ์ข ์๋์ด, ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ๊ณผ ํ ์คํธ ์ฉ์ด์ฑ๋ ํฌ๊ฒ ๋จ์ด์ก์ต๋๋ค. ์ด๋ฌํ ๊ตฌ์กฐ๋ ์๊ฐ์ด ์ง๋ ์๋ก ์ฝ๋์ ๋ณต์ก์ฑ์ ์ฆ๊ฐ์์ผ, ์ ์ง๋ณด์์ ๊ธฐ๋ฅ ํ์ฅ์ ์ ์ ๋ ์ด๋ ต๊ฒ ๋ง๋ค์์ต๋๋ค.
2. ๋จ์ผ Map ๊ธฐ๋ฐ์ ์ํ ๊ด๋ฆฌ์ ๋ฉ๋ชจ๋ฆฌ ๋นํจ์จ์ฑ
ํนํ ChatManager ๋ ๋ชจ๋ ์ฑํ
๋ฐฉ์ ๋ฉ์์ง๋ฅผ ์๋์ ๊ฐ์ chats ๋ผ๋ ๋ณ์์ ๋ด์ ๊ด๋ฆฌํ์ต๋๋ค. ์ด ๋ณ์๋ ์ฑํ
๋ฐฉ ID(String
)๋ฅผ ํค๋ก, ํด๋น ์ฑํ
๋ฐฉ์ ๋ฉ์์ง ๋ฆฌ์คํธ(List<ChatDto>
)๋ฅผ ๊ฐ์ผ๋ก ๊ฐ์ง๋ Map ํํ์์ต๋๋ค.
private val _chats = MutableStateFlow<Map<String, List<ChatDto>>>(mapOf())
val chats = _chats.asStateFlow()
์ด๋ฌํ ๊ตฌ์กฐ๋ ๊ณผ๋ํ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๊ณผ ์ฑ๋ฅ ์ ํ๋ผ๋ ๋ ๊ฐ์ง ๋ฌธ์ ๋ฅผ ์ผ๊ธฐํ์ต๋๋ค. ๋จผ์ , ๋ชจ๋ ์ฑํ ๋ฐฉ์ ๋ฉ์์ง๋ฅผ ํ๋์ Map์ ์ ์ฅํ๋ ๋ฐฉ์์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ฆ๊ฐ๋ก ์ด์ด์ก์ต๋๋ค. ์ฑํ ๋ฐฉ ์์ ๊ฐ ์ฑํ ๋ฐฉ์ ๋ฉ์์ง ์๊ฐ ์ฆ๊ฐํ ์๋ก, chats์ ์ ์ฅ๋๋ ๋ฐ์ดํฐ์ ์๋ ๋์ด๋๊ฒ ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ 10๊ฐ์ ์ฑํ ๋ฐฉ์ ์ฐธ์ฌํ๊ณ , ๊ฐ ์ฑํ ๋ฐฉ์ 10,000๊ฐ์ ๋ฉ์์ง๊ฐ ์๋ค๋ฉด, chats์๋ 10๋ง ๊ฐ์ ๋ฉ์์ง๊ฐ ์ ์ฅ๋๋ ๊ฒ์ ๋๋ค. ํนํ ChatManager๋ Singleton ๊ฐ์ฒด๋ก, ์ฑ์ด ์คํ๋๋ ๋์ ๊ณ์ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ผ๊ฐ๊ณ , chats ๋ํ ์ฑ์ด ์ข ๋ฃ๋ ๋๊น์ง ์ ์ง๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ฌ์ฉ์๊ฐ ์ฑํ ๋ฐฉ์ ๋๊ฐ ํ์๋, ํด๋น ์ฑํ ๋ฐฉ์ ๋ฉ์์ง ๋ฐ์ดํฐ๋ chats์ ๊ณ์ ๋จ์์๊ฒ ๋๊ณ , ๋ ์ด์ ์ฌ์ฉ๋์ง ์์์๋ ๋ถ๊ตฌํ๊ณ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐจ์งํ๊ฒ ๋ฉ๋๋ค. ์ด๋ฌํ ํ์์ด ๋ฐ๋ณต๋๋ฉด, ์ฑ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ๊ณ์ํด์ ์ฆ๊ฐํ๊ฒ ๋๊ณ , ๊ฒฐ๊ตญ ๋ฉ๋ชจ๋ฆฌ ๋์(Memory Leak)๋ก ์ด์ด์ง ์ํ์ด ์์์ต๋๋ค.
๋ํ, chats ๋ณ์์ ์ ์ฅ๋ ๋ฉ์์ง ๋ฐ์ดํฐ๊ฐ ๋ง์์ง์๋ก, ๋ฉ์์ง๋ฅผ ๊ฒ์ํ๊ฑฐ๋ ์ ๋ฐ์ดํธํ๋ ๋ฐ ํ์ํ ์๊ฐ๋ ์ฆ๊ฐํ์ฌ ์ฑ๋ฅ ์ ํ๋ฅผ ์ผ์ผ์ผฐ์ต๋๋ค. ํนํ ๊ธฐ์กด ํ์ด์ง ๋ฐฉ์์, ์ฌ์ฉ์๊ฐ ์คํฌ๋กคํ ๋๋ง๋ค ๋ฉ์์ง๋ฅผ ์ ํ ์์ด ๊ธฐ์กด ๋ฆฌ์คํธ์ ์ถ๊ฐํ๋ ๋ฐฉ์์ด์๊ธฐ ๋๋ฌธ์, ์ฌ์ฉ์๊ฐ ์คํฌ๋กค์ ๋ง์ด ํ๊ณ ์ฑํ ๋ฐฉ์ ์ค๋ ์ฌ์ฉํ ์๋ก ๋ฉ์์ง ๋ฆฌ์คํธ๋ ๊ณ์ํด์ ์ปค์ก์ต๋๋ค. ์ด๋ก ์ธํด ์ฌ์ฉ์์๊ฒ ๋ณด์ด์ง ์๋ ๊ณผ๊ฑฐ ๋ฉ์์ง๊น์ง ๋ฉ๋ชจ๋ฆฌ์ ์ ์งํด์ผ ํ๊ณ , ๋ฉ์์ง ๋ฆฌ์คํธ๊ฐ ์ปค์ง์๋ก ๋ฉ์์ง ํ์์ด๋ ์กฐ์์ ๋ ๋ง์ ์๊ฐ์ด ์์๋์์ต๋๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก, ์ด๋ฌํ ๋นํจ์จ์ ์ธ ์ํ ๊ด๋ฆฌ์ ํ์ด์ง ๋ฐฉ์์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ํ์ํค๋ ์ฃผ์ ์์ธ์ด ๋์์ต๋๋ค.
3. ๋ณต์กํ ๋ฐ์ดํฐ ํ๋ฆ๊ณผ ๋ถํ์ํ ์ฐ์ฐ์ ๋ฐ๋ณต
ChatManager์ ChatViewModel ๊ฐ์ ๋ฐ์ดํฐ ํ๋ฆ ๋ํ ๋ณต์กํ์ต๋๋ค.
(ํธ์๋ฅผ ์ํด usecase, repository ๋ฅผ ๊ฑฐ์น์ง ์๊ณ ์ง์ DB ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ผ๋ก ํํํ์ต๋๋ค.)
์์ ๋ค์ด์ด๊ทธ๋จ์ ์ฑํ ๋ฐฉ์์ ๋ฉ์์ง๋ฅผ ๋ถ๋ฌ์ค๋ ๊ณผ์ ์ ๊ฐ๋ตํ ๋ณด์ฌ์ฃผ๋๋ฐ, ๋ฐ์ดํฐ๊ฐ ๋ถํ์ํ๊ฒ ์ฌ๋ฌ ๋จ๊ณ๋ฅผ ๊ฑฐ์น๋ฉฐ ๋นํจ์จ์ ์ผ๋ก ํ๋ฅด๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ํนํ ViewModel์ View์์ ์ ๋ฌ๋ฐ์ ์ก์ ์ ์ง์ ์ฒ๋ฆฌํ์ง ์๊ณ ChatManager์ ์์ํ๋ ๋จ์ ์ค๊ฐ ์ญํ ๋ง์ ์ํํ๊ณ ์์์ต๋๋ค. ๋ํ, ChatManager ๊ฐ StateFlow ๋ก ๋ฐฉ์ถํ ๋ฐ์ดํฐ๋ฅผ ๋ค์ View ๋ฅผ ํตํด ์ ๋ฌ๋ฐ์ ๋งคํํ๊ณ ์์์ต๋๋ค. ์ด์ฒ๋ผ ChatManager์ ViewModel์ ์ญํ ์ด ๋ช ํํ ๋ถ๋ฆฌ๋์ง ์์ ๋ฐ์ดํฐ ํ๋ฆ์ด ๋ณต์กํด์ง๊ณ , ๋ฐ์ดํฐ ๊ด๋ฆฌ ์ฃผ์ฒด๊ฐ ์ฌ๋ฌ ๊ฐ๋ก ๋ถ์ฐ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
์ด์ ๋ํด, ๋ฐ์ดํฐ๊ฐ ์
๋ฐ์ดํธ ๋ ๋๋ง๋ค ChatManager ์ List<ChatDto>
๋ฅผ ChatViewModel ์ UI ๋ชจ๋ธ์ธ List<ChatMessage>
๋ก ๋ณํํ๋ ๊ณผ์ ์์ ๋ถํ์ํ ์ฐ์ฐ์ด ๋ฐ๋ณต์ ์ผ๋ก ์ํ๋๋ ๋ฌธ์ ๋ ์์์ต๋๋ค.
์ผ๋ถ ๋ฉ์์ง๋ง ์ถ๊ฐ, ์ญ์ , ์
๋ฐ์ดํธ๋๋๋ผ๋ ๋ฆฌ์คํธ ์ ์ฒด๋ฅผ ์๋ก์ด ๊ฐ์ฒด๋ก ๋ค์ ์์ฑํ์ฌ ๋ชจ๋ ๋ฉ์์ง๋ฅผ ๋ค์ ๋งคํํ๋ ๊ตฌ์กฐ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๊ทธ๋ฌ๋ค๋ณด๋ ๋ ์ง ๊ตฌ๋ถ์ ์ถ๊ฐ์ ๊ฐ์ UI ๊ด๋ จ ๋ก์ง์ ์ฒ๋ฆฌํ ๋๋ ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ด๋ฏธ ์ํํ ์ฐ์ฐ์ ๋๋ค์ ์ฒ๋ฆฌํด์ผ ํด์ ๋นํจ์จ์ฑ์ ๋์ฑ ๋์ด๋ฌ์ต๋๋ค.
์๋ก์ด ์ํคํ ์ฒ ๋์ ๋ฐ ์ฑ๋ฅ ๊ฐ์
1. MVI ํจํด ๋ฐ Reducer ๋์
์ฑํ ๋ฆฌ๋ด์ผ์ ์งํํ๋ฉด์ ๊ฐ์ฅ ์ค์ํ๊ฒ ์๊ฐํ ์ ์ ์ฑ ์์ ๋ช ํํ ๋ถ๋ฆฌํ๊ณ , ์ํ ๊ด๋ฆฌ๋ฅผ ๋จ์ํํ๋ ๊ฒ์ด์์ต๋๋ค. ๊ธฐ์กด์๋ ChatManager์ ChatViewModel์ด ๋ณต์กํ๊ฒ ์ฝํ ์์ด ๋ฐ์ดํฐ ํ๋ฆ์ ํ์ ํ๊ธฐ ์ด๋ ค์ ๊ณ , ์ํ ๋ณ๊ฒฝ์ด ์ฌ๋ฌ ๊ณณ์์ ๋ฐ์ํ์ฌ ์์ธกํ๊ธฐ ํ๋ค์์ต๋๋ค. ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด MVI(Model-View-Intent) ํจํด๊ณผ Reducer๋ฅผ ๋์ ํ์ฌ ๋ฐ์ดํฐ ํ๋ฆ์ ๊ฐ์ ํ์ต๋๋ค. MVI ํจํด์ ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ์ ํตํด ์ํ ๋ณํ๋ฅผ ์์ธก ๊ฐ๋ฅํ๊ฒ ๋ง๋ค๊ณ , Reducer๋ ์ด์ ์ํ์ ์๋ก์ด ์ก์ ์ ๊ธฐ๋ฐ์ผ๋ก ์๋ก์ด ์ํ๋ฅผ ์์ฑํ๋ ์์ ํจ์๋ก, ์ํ ์ ๋ฐ์ดํธ ๋ก์ง์ ๋ช ํํ๊ฒ ๋ถ๋ฆฌํ๋ ๋ฐ ๋์์ ์ค๋๋ค.
(ํธ์๋ฅผ ์ํด usecase, repository ๋ฅผ ๊ฑฐ์น์ง ์๊ณ ์ง์ DB ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ผ๋ก ํํํ์ต๋๋ค.)
๊ฐ์ ๋ ์ํคํ ์ฒ์ ๋ค์ด์ด๊ทธ๋จ์ ์ดํด๋ณด๋ฉด, ๋ฉ์์ง๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ์ดํฐ ํ๋ฆ์ด ์ด์ ๋ณด๋ค ํจ์ฌ ๊ฐ๊ฒฐํด์ง ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. View๋ ๋ ์ด์ ์ฌ๋ฌ ๊ฐ์ StateFlow๋ฅผ ๊ตฌ๋ ํ๋ ๋์ , ์ค์ง ํ๋์ UiState๋ง์ ๊ด์ฐฐํ์ฌ UI๋ฅผ ์ ๋ฐ์ดํธํ๋ ์ญํ ์ ์ง์คํฉ๋๋ค. ๋ํ, ๊ธฐ์กด์๋ ViewModel์ด ChatManager์ ์์กดํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์๊ธฐ ๋๋ฌธ์ ๋ฐ์ดํฐ ํ๋ฆ์ด ๋ณต์กํ๊ณ ChatManager์ ์ญํ ์ด ๊ณผ์ค๋๋ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. ํ์ง๋ง ๊ฐ์ ๋ ๊ตฌ์กฐ์์๋ ViewModel์ด ๋ ์ด์ ChatManager๋ฅผ ๊ฑฐ์น์ง ์๊ณ ์ง์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋๋ก ๋ณ๊ฒฝ๋์ด, ๋ฐ์ดํฐ ํ๋ฆ์ด ๋ํญ ๋จ์ํ๋์์ต๋๋ค. ๋ํ UI ์ํ๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋ก์ง์ Reducer๊ฐ ๋ด๋นํ๋๋ก ๋ณ๊ฒฝ๋์ด, ์๋ก์ด ๋ฉ์์ง๊ฐ ๋์ฐฉํ๋ฉด Reducer๋ ๊ธฐ์กด ๋ฉ์์ง ๋ชฉ๋ก๊ณผ ์๋ก์ด ๋ฉ์์ง๋ฅผ ๊ฒฐํฉํด ์๋ก์ด UiState๋ฅผ ์์ฑํฉ๋๋ค. ์ด์ฒ๋ผ ์ํ ์ ๋ฐ์ดํธ ๋ก์ง์ด Reducer๋ผ๋ ํ๋์ ์ฅ์๋ก ์ง์ค๋๋ฉด์, ์ํ ๋ณํ๋ฅผ ์์ธกํ๊ณ ๊ด๋ฆฌํ๊ธฐ๊ฐ ํจ์ฌ ์ฉ์ดํด์ก์ต๋๋ค. ์ด๋ฌํ ๋ณํ๋ฅผ ํตํด, ๊ธฐ์กด์ ๊ฑฐ๋ํ๊ณ ๋ณต์กํ๋ ChatManager๋ ์์ฐ์ค๋ฝ๊ฒ ์ ๊ฑฐ๋์๊ณ , ๋ณต์กํ๋ ๋ฐ์ดํฐ ํ๋ฆ์ ๋จ๋ฐฉํฅ ์ํ ๊ตฌ์กฐ๋ก ๋จ์ํ๋์์ต๋๋ค.
2. ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ์ต์ ํ: ๋ฆฌ์คํธ ํฌ๊ธฐ ์ ํ
๋์๊ฐ, ์ฑํ ๋ฉ์์ง๋ค์ ๊ด๋ฆฌํ๋ ๋ฐฉ์์ ๊ทผ๋ณธ์ ์ผ๋ก ๊ฐ์ ํ์ต๋๋ค. ๊ธฐ์กด์๋ ๋ชจ๋ ์ฑํ ๋ฐฉ์ ๋ฉ์์ง๋ฅผ chats๋ผ๋ ํ๋์ Map ๋ณ์์ ๋ด์ ๊ด๋ฆฌํ๋ ๋ฐฉ์์ด์๊ธฐ ๋๋ฌธ์, ํน์ ์ฑํ ๋ฐฉ์ ๋ฉ์์ง๋ฅผ ์ฐพ๊ฑฐ๋ ์ ๋ฐ์ดํธํ๋ ๋ฐ ์ด๋ ค์์ด ์์์ต๋๋ค. ๋ํ, ์ฑํ ๋ฐฉ๊ณผ ๋ฉ์์ง๊ฐ ์์ผ์๋ก ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ์ฆ๊ฐํ๋ ๋ฌธ์ ๋ ์์์ต๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด, ๊ฐ๋ณ ์ฑํ ๋ฐฉ์ ViewModel์์ ๋ฉ์์ง ๋ฐ์ดํฐ๋ฅผ ๋ ๋ฆฝ์ ์ผ๋ก ๊ด๋ฆฌํ๋๋ก ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ์ต๋๋ค. ์ด์ ๊ฐ ์ฑํ ๋ฐฉ์ ViewModel์ ์์ ์ ๋ฉ์์ง ๋ฐ์ดํฐ๋ค์ ๋ ๋ฆฝ์ ์ผ๋ก ๊ด๋ฆฌํ๋ฏ๋ก, ๋ฉ์์ง ๊ด๋ฆฌ๊ฐ ํจ์ฌ ํจ์จ์ ์ด๊ณ ๋ช ํํด์ก์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฉ์์ง ๋ฐ์ดํฐ๋ค์ ์ฉ๋์ ๋ง๊ฒ ์ธ๋ถํํ์ฌ ๊ด๋ฆฌํ ์๋ ์๊ฒ ๋์์ต๋๋ค.
data class ChatRoomState(
val poolMessages: List<ChatMessage>,
val recentMessages: List<ChatMessage>,
val sendingMessages: List<SendingChatMessage>,
...
) : State
๊ฐ๊ฐ์ ์ญํ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- poolMessages: ์ต๊ทผ ๋ฉ์์ง ์ด์ ์ ์ค๋๋ ๋ฉ์์ง๋ค์ ์ ์ฅํ๋ ๋ฆฌ์คํธ์ ๋๋ค. ์์ ๋กญ๊ฒ ๋ฉ์์ง๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ ์ ์๋ ๋ฉ์์ง ํ ์ญํ ์ ํ๋ฉฐ, ํฌ๊ธฐ๋ 2000๊ฐ๋ก ์ ํ๋ฉ๋๋ค.
- recentMessages: ์ฌ์ฉ์๊ฐ ์์ง ์ฝ์ง ์์ ๋ฉ์์ง๋, ์๋กญ๊ฒ ์ถ๊ฐ๋ ๋ฉ์์ง๋ค์ ์ ์ฅํ๋ ๋ฆฌ์คํธ์ ๋๋ค. ์ด ๋ฆฌ์คํธ๋ฅผ ํตํด ์ฌ์ฉ์๋ ์๋ก์ด ๋ฉ์์ง๋ฅผ ๋น ๋ฅด๊ฒ ํ์ธํ ์ ์์ต๋๋ค.
- sendingMessages: ์ฌ์ฉ์๊ฐ ํ์ฌ ์ ์ก ์ค์ธ ๋ฉ์์ง๋ค์ ์ ์ฅํ๋ ๋ฆฌ์คํธ์ ๋๋ค. ์ด ๋ฆฌ์คํธ๋ฅผ ํตํด ๋ฉ์์ง ์ ์ก ์ํ๋ฅผ ๊ด๋ฆฌํ๊ณ , ์ ์ก ์คํจ ์ ์ฌ์ ์ก ๋ฑ์ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์์ต๋๋ค.
ํนํ poolMessages์์ ์ฑํ ๋ฐฉ ์คํฌ๋กค์ ๋ฐ๋ผ ์ฌ์ฉ์์๊ฒ ๋ณด์ด์ง ์๋ ๋ฐ์ดํฐ๋ ๋ฉ๋ชจ๋ฆฌ์์ ์ ๊ฑฐํ๊ณ , ํ์ ์ ๋ค์ ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ์ต์ ํํ์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๊ฐ ์ฑํ ๋ฐฉ์ ์๋ก ์คํฌ๋กคํ์ฌ ๊ณผ๊ฑฐ ๋ฉ์์ง๋ฅผ ํ์ธํ๋ ๊ฒฝ์ฐ, poolMessages์ ์๋ ๋ฉ์์ง๋ ์๋ฒ๋ก๋ถํฐ ๊ฐ์ ธ์ ์ถ๊ฐํ๊ณ , ์ด ๋ ๋ฆฌ์คํธ์ ํฌ๊ธฐ๊ฐ POOL_MESSAGE_LIMIT ๋ณด๋ค ํฌ๋ค๋ฉด ํ๋ฉด์ ๋ณด์ด์ง ์๋ ์ต๊ทผ ๋ฉ์์ง๋ค์ ์ ๊ฑฐํฉ๋๋ค.
data class AddPoolMessages(val messages: List<ChatMessage>, val isPrepend: Boolean) : ChatRoomReducer(
reducer = { state ->
val dropSize = messages.size - POOL_MESSAGES_LIMIT
val poolMessages = messages
.takeIf { it.size <= POOL_MESSAGES_LIMIT }
?: if (isPrepend) messages.dropLast(dropSize) else messages.drop(dropSize)
state.copy(
poolMessages = poolMessages
)
}
)
์ด๋ฌํ ๋ฐฉ์์ ํตํด, ์ฌ์ฉ์๊ฐ ์ฑํ ๋ฐฉ์ ํ๋ฐํ๊ฒ ์ฌ์ฉํ๋๋ผ๋ ํ์ ์ด์์ ๋ฐ์ดํฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ ์งํ์ง ์์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ๊ณผ๋ํ๊ฒ ์ฆ๊ฐํ๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์๊ฒ ๋์์ต๋๋ค.
3. ํจ์จ์ ์ธ ์ฐ์ฐ ์ฒ๋ฆฌ ๋ฐ ์ญํ ๋ถ๋ฆฌ
์์ ์ค๋ช ํ ๊ฐ์ ์ฌํญ๋ค์ ํตํด, ๋ชจ๋ ์ฑํ ๋ฐฉ์ ๋ฉ์์ง๋ฅผ ๋ด๊ณ ์๋ ChatManager์ chats ๋ณ์๊ฐ ๋ ์ด์ ํ์ ์์ด์ง๋ฉด์, ๋ถํ์ํ ์ฐ์ฐ ๋ํ ๋ํญ ๊ฐ์ํ์ต๋๋ค. ๊ธฐ์กด์๋ ์ผ๋ถ ๋ฉ์์ง๋ง ์ถ๊ฐ๋๊ฑฐ๋ ์์ ๋๋๋ผ๋ ๋ฆฌ์คํธ ์ ์ฒด๋ฅผ ์๋ก ์์ฑํ๊ณ ๋ค์ ๋งคํํด์ผ ํ์ง๋ง, ์ด์ ๋ ๊ธฐ์กด ๋ฆฌ์คํธ์ ์๋ก์ด ๋ฉ์์ง๋ง ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ๋ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝ๋์ด, ๋ ์ด์ ์ ์ฒด ๋ฉ์์ง๋ฅผ ๋ค์ ๋งคํํ ํ์๊ฐ ์์ด์ก์ต๋๋ค. ์ด๋ก ์ธํด ๋ถํ์ํ ๋ฆฌ์คํธ ๋ณํ ์ฐ์ฐ์ด ํฌ๊ฒ ์ค์ด๋ค์๊ณ , ์ฑ๋ฅ์ด ํฅ์๋์์ต๋๋ค.
๋ ๋์๊ฐ, ViewModel์ ๋ฐ์ดํฐ ๋ ์ด์ด์์ ๋ฉ์์ง๋ฅผ ๊ฐ์ ธ์ค๊ณ , ์ญ์ ํ๊ณ , ๋ฒ์ญํ๋ ๋ฑ์ ๋น์ฆ๋์ค ๋ก์ง ์ํ๊ณผ ์ํ ๊ด๋ฆฌ์ ์ง์คํ๋๋ก ๊ฐ์ ํ๊ณ , UiState๋ก์ ๋งคํ์ด๋ ๋ ์ง ๊ตฌ๋ถ์ ์ถ๊ฐ์ ๊ฐ์ UI ๊ด๋ จ ์์ ์ ๋ค๋ฅธ ํด๋์ค๋ก ๋ถ๋ฆฌํ์์ต๋๋ค. ์ด๋ก์จ ๋ณต์กํ๊ฒ ์ฝํ ์๋ ViewModel์ ์ญํ ์ด ๋ถ์ฐ๋๋ฉด์ ๊ฐ ํด๋์ค์ ์ฑ ์์ด ๋ช ํํด์ก๊ณ , ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ด ํฌ๊ฒ ํฅ์๋์์ต๋๋ค.
๋ง๋ฌด๋ฆฌํ๋ฉฐ
์ด๋ฒ fromm ์ฑํ ์์คํ ๋ฆฌ๋ด์ผ์ ํตํด ์์ ์ฑ๊ณผ ์ฑ๋ฅ, ํ์ฅ์ฑ, ์ ์ง๋ณด์์ฑ ๋ฑ ๋ง์ ์ธก๋ฉด์์ ๊ฐ์ ์ ํ์์ต๋๋ค. ์ด์ ์๋ก์ด ๊ตฌ์กฐ๋ฅผ ๋ฐํ์ผ๋ก ๋์ฑ ํจ์จ์ ์ด๊ณ ๋น ๋ฅด๊ฒ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ณ ์ ์ง๋ณด์ ํ ์ ์๊ธฐ๋ฅผ ๊ธฐ๋ํฉ๋๋ค. ์์ผ๋ก๋ ์ง์์ ์ธ ๊ฐ์ ์ ํตํด ๋ ๋์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ๊ณ ๋ ์ข์ ์๋น์ค๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๊ณ์ํด์ ๋ฐ์ ํด ๋๊ฐ๊ฒ ์ต๋๋ค. ๊ฐ์ฌํฉ๋๋ค!