์์กด์ฑ ์ฃผ์ ์ด๋ผ.. ๋๋ฌด๋๋ ์ต์ํ์ง ์์ ๋ฌธ์ฅ์ด๋ค.
๋จ์๊ฒ ์์กดํ์ง๋ง๊ณ ์ฃผ์ฒด์ ์ผ๋ก ์ด์ ๋ผ๋ ๋ง์ ์ฌ์ฉํ ๋๋ง ์ผ๋ ๋จ์ด๋ฅผ ๊ฐ๋ฐํ ๋ ์ฌ์ฉํ๋ ์ด์ํ๊ณ ๋จ๋ฒ์ ์ดํด๊ฐ ๋์ง ์๋๋ค.
์์กด์ฑ ์ฃผ์ (์์กด๊ด๊ณ ์ฃผ์ )! Dependency Injection(DI)
๋ํ๋์ ์ธ์ ์ , ์์กด์ฑ์ฃผ์ ์ ๋ํด ๊ฐ๋จํ๊ฒ ์ค๋ช ํ๊ณ ์ถ์๋ฐ ๋ญ๋ผํด์ผ๋ ์ง ๋ชจ๋ฅด๊ฒ ๋ค.
→ ํ์ค์ ์ ์ ํ ์ ์๊ณ , ์ ์๋ ํ์ค์ ๋ฐํ์ผ๋ก ๊ฐ์ ์ค๊ณ๋ฅผ ํ๊ฒ ํ์ฌ์ค๋๋ค.(์ญ์๋ ํ ๋ฒ์ ์ดํด๊ฐ ๋์ง ์๋๋ค.)
์ข ๋ ๊ฐ๊น๊ฒ ์ ์ํ๋ค๋ฉด,
”์์กด๋์ B๊ฐ ๋ณํ๋ฉด, ๊ทธ๊ฒ์ด A์ ์ํฅ์ ๋ฏธ์น๋ค .” - ์ด์ผ๋ฏผ, ํ ๋น์ ์คํ๋ง 3.1, ์์ด์ฝ(2012), p113
B๊ฐ ๋ณ๊ฒฝ๋๊ฑฐ๋ ํ์์ด ๋ฐ๋๋ฉด A์ ์ํฅ์ด ๊ฐ๋ค.
(์ฌ์ง : Jacob)
๐ฅ ํ์๋ฅผ ๊ฐ๋ฅด์น๋ ํ๊ถ๋ ์ฌ๋ฒ๋์ ๊ตญ๊ธฐ์์์ ์ง์ ํ ํ์์ ํ์์ ์์กดํ๋ค.
์ง์ ๋์๋ ํ์๊ฐ ๋ณํํ๊ฒ ๋์์ ๋, ๋ณํ๋ ํ์์ ๋ฐ๋ผ์ ํ๊ถ๋ ์ฌ๋ฒ๋์ ์์ด๋ค์๊ฒ ๋ฐ๋ ํ์๋๋ก ๊ฐ๋ฅด์ณ์ผํ๋ค.
ํ์์ ๋ณํ๊ฐ ์ฌ๋ฒ๋์ ๊ต์ก์ ์ํฅ์ ๋ฏธ์ณค๊ธฐ ๋๋ฌธ์ “์ฌ๋ฒ๋์ ๊ตญ๊ธฐ์์์ ์ง์ ํ ํ์ ํ์์ ์์กดํ๋ค.” ๋ผ๊ณ ๋งํ ์ ์๋ค.
(๋ชจ๋ ์๊ธฐ๊ฐ ์ดํดํ๋ ๋ฐฉ๋ฒ์ด ๋ค๋ฅด๊ธฐ์ ์์ ์ ์ํฉ์ ๋ง๊ฒ ๋์ ์์ผ๋ณด๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.)
DI ๊ตฌํ ๋ฐฉ๋ฒ
DI๋ ์์กด๊ด๊ณ๋ฅผ ์ธ๋ถ์์ ๊ฒฐ์ ํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, ํด๋์ค ๋ณ์๋ฅผ ๊ฒฐ์ ํ๋ ๋ฐฉ๋ฒ๋ค์ด ๊ณง DI๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ด๋ค. ๋ฐํ์ ์์ ์ ์์กด๊ด๊ณ๋ฅผ ์ธ๋ถ์์ ์ฃผ์ ํ์ฌ DI ๊ตฌํ์ด ์์ฑ๋๋ค.
์์กด์ฑ ์ฃผ์ ์
// koin์ ์ฌ์ฉํ ๊ฒ์ด ์๋.
class Poomsae {
fun start() {
...
}
}
โ
class TaekwondoCoach {
private val poomsae = Poomsae()
โ
fun start() {
poomsae.start()
}
}
โ
fun main(args: Array) {
val taekwondoCoach = TaekwondoCoach()
taekwondoCoach.start()
}
โ
์์กด์ฑ ์ฃผ์ ํ
// koin์ ์ฌ์ฉํ ๊ฒ์ด ์๋.
...
โ
class TaekwondoCoach(private val poomsae: Poomsae) {
// ์์กด์ฑ ์ฃผ์
์
// ์์์ ์ ์ธํด์ ์ฌ์ฉํ๋์ง / ์ฌ์ฉํ๋ ๊ณณ์์ ์ ์ธํด์ ๋ฃ์ด์ฃผ๋ ์ฐจ์ด โฌ๏ธ
fun start() {
poomsae.start()
}
}
โ
fun main(args: Array) {
val poomsae = Poomsae()
val taekwondoCoach = TaekwondoCoach(poomsae)
taekwondoCoach.start()
}
์์กด์ฑ ์ฃผ์ ์ฅ์
- ์ฌ์ฌ์ฉ์ฑ โฌ๏ธ.
- ํ ์คํธ์ ์ฉ์ด
- ์ฝ๋ ๋จ์ํ
- ์ข ์์ ์ด๋ ์ฝ๋์ ์ โฌ๏ธ
- ์ฌ์ฉ ์ด์ ํ์ ํ๊ธฐ ์์. (์ฝ๋๋ฅผ ์ฝ๊ธฐ ์ฌ์์ง)
- ์ข ์์ฑ์ด ๊ฐ์(๊ตฌ์ฑ ์์์ ์ข ์์ฑ์ด ๊ฐ์ → ๋ณ๊ฒฝ์ ๋ฏผ๊ฐ โ.)
- ๊ฒฐํฉ๋๋ ๋ฎ์ถ๋ฉด์ ์ ์ฐ์ฑ๊ณผ ํ์ฅ์ฑ์ ํฅ์์ํฌ ์ ์์.
- ๊ฐ์ฒด๊ฐ์ ์์กด๊ด๊ณ๋ฅผ ์ค์ ๊ฐ๋ฅ(์์ ๊ฑฐ๋ ์ค์ผ ์ ์์)
- ๋ฑ๋ฑ…
ํ์ง๋ง ๋จ์ ๋ ์กด์ฌํ์ฃ .
- ์์กด์ฑ ์ฃผ์ ์ ์ํ ์ ํ์์ ์ด ํ์ํจ.
- ์ฝ๋๋ฅผ ์ถ์ ํ๊ณ ์ฝ๊ธฐ๊ฐ ์ด๋ ค์์ง.( → ๋จ์ํ ๋๋ฉด์)
- ๊ฐ๋จํ ํ๋ก๊ทธ๋จ์ ๋ง๋ค ๋๋ ๋ฒ๊ฑฐ๋ก์
์ ํ๋จํด์ ์ฌ์ฉํ๊ธธ ๋ฐ๋.
ํ์ง๋ง ์ ์ฝ๋์ฒ๋ผ ์๋์ผ๋ก ์ผ์ผํ DI(์์กด์ฑ ์ฃผ์ )ํ๊ธฐ์ ๋๋ฌด ๊ท์ฐฎ๋ค.. ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฐ์!!
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ 3๊ฐ์ง ์ ๋ ์๊ณ ์๋ค
Hilt, Dagger2, Koin ์ด ์๋๋ฐ ๊ฐ๋จํ๊ฒ ์ด๊ฒ๋ค์ ์ฐจ์ด์ ์ด๋ผ๊ณ ํ๋ฉด ์๋์ ์ ๋ฆฌํด๋ดค๋ค.
Hilt(Jetpack) | Dagger2 | Koin | |
Java | O | O | X |
Kotlin | O | O | O |
๋ฌ๋์ปค๋ธ | ๋ฎ์ | ๋์ | ๋ฎ์ |
์๋ฌ๊ฒ์ถ ์์ | Compile Time | Compile Time | Runtime |
์ค์ ํ๋ก์ ํธ ๊ฒ์ฆ | beta๋ฒ์ (์กฐ๊ธ์ฉ ๋ณด์) | ๋ง์ ์ฑ์์ ๊ฒ์ฆ๋จ | ๋ง์ ์ฑ์์ ๊ฒ์ฆ๋จ |
๊ทธ๋์ ์ง๊ธ ์์ ํ๋ก์ ํธ์ ์ ์ฉํ๊ณ ๊ฒ์ฆ์ด ๋์๊ณ ์กฐ๊ธ ๊ณต๋ถ๋ฅผ ๋ ํด๋ ๋น์ฅ ์ ์ฉ์ํค๋ฉด์ ๋ฐฐ์ฐ๊ณ ์ถ์๊ธฐ ๋๋ฌธ์ Koin์ ํ๋ก์ ํธ์ ์ ์ฉ์ ๊ฒฐ์ ํ์ต๋๋ค~ (๐ต์์ด๋ฌ๋ํ๊ฒ๋ ์ ์ฉํ๊ธฐ ๊ฐ์ฅ ์ข์ ์๊ธฐ๋ ์์ง ํ๋ก์ ํธ๊ฐ ์์๊ท๋ชจ์ผ ๋ ๋ผ๊ณ ๋ค์์ด์)
(๐บ๐ผ๋ชจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด๋ณธ ๊ฒ์ด ์๋๊ธฐ ๋๋ฌธ์ ์์ง ๋ญ๊ฐ ์ข๋ค ๋งํ ์ ์์ง๋ง ๊ฒฝํ์ ์์ผ๋ฉด์ ์ฌ๋ฌ๊ฐ์ง ๊ณต๋ถ ํด๋ณผ ์์ .)
1. gradle ์ถ๊ฐ
// build.gradle (project)
buildscript {
...
ext.koin_version = '3.1.0'
โ
repositories {
jcenter()
}
}
โ
// build.gradle (app)
dependencies {
...
implementation("io.insert-koin:koin-core:$koin_version")
implementation("io.insert-koin:koin-android:$koin_version")
implementation("io.insert-koin:koin-test:$koin_version")
...
}
2. Koin ์ฌ์ฉ!
์ค์น๊ฐ ๋๋๋ฉด ๋ณธ๊ฒฉ์ ์ผ๋ก ์ฌ์ฉ!
class SampleRepository() {
val sampleData = "Sample Data!"
}
โ
class SampleController(val repository: SampleRepository) {
fun printSampleData() {
Log.d("Print sample data", repository.sampleData)
}
}
โ
class SampleViewModel : ViewModel() {
private var _isLoading = MutableLiveData<Boolean>()
val isLoading: LiveData<Boolean> = _isLoading
}
val appModule = module {
single { SampleRepository() }
factory { SampleController(get()) }
}
- single : ์ฑ์ด ์คํ๋๋ ๋์ ๊ณ์ ์ ์ง๋๋ ์ฑ๊ธํค ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค.
- factory : ์์ฒญํ ๋๋ง๋ค ๋งค๋ฒ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค.
- get() : ์ปดํฌ๋ํธ ๋ด์์ ์๋ง์ ์์กด์ฑ์ ์ฃผ์
๋ฐ์ต๋๋ค.
- ์ ์์ ์์๋ SampleRepository ํ์ ์ผ๋ก ์ ์ธ๋์ด ์์ผ๋ฏ๋ก ์ด๋ฏธ ์์ฑ๋ ๊ฐ์ฒด ์ค SampleRepository ํ์ ์ ์๋ง์ ๊ฐ์ฒด๋ฅผ Koin์ด ์ฃผ์ ํด์ค๋๋ค.
val viewModelModule = module {
viewModel { SampleViewModel() }
}
3. ๋ชจ๋ ๋ฑ๋ก
์ด์ Koin์ ํด๋น ๋ชจ๋์ ๋ฑ๋กํ ์ฐจ๋ก์ ๋๋ค.
Application ํด๋์ค์(ํ๋ก์ ํธ์ Application ํด๋์ค๊ฐ ๋ฐ๋ก ์๋ค๋ฉด ์๋ก ์์ฑํฉ๋๋ค) onCreate LifeCycle์์ startKoin์ ํธ์ถํ๊ณ ์์์ ์ ์ธํ ๋ชจ๋ ๋ณ์๋ฅผ ๋๊ฒจ์ค๋๋ค.
class MyApplication: Application() {
override fun onCreate() {
super.onCreate()
initKoin()
}
โ
private fun initKoin() {
startKoin {
androidLogger(Level.NONE)
androidContext(this@MyApplication)
modules(
appModule,
adapterModule,
viewModelModule
)
}
}
}
- androidLogger() : AndroidLogger๋ฅผ Koin logger๋ก ์ฌ์ฉํฉ๋๋ค.
- androidContext(...) : ํด๋น ์๋๋ก์ด๋ context๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- modules(...) : ์ฌ์ฉํ ๋ชจ๋์ ๋ฑ๋กํฉ๋๋ค.
์ฐธ๊ณ ๋ก Application ํด๋์ค๋ฅผ ์๋ก ์์ฑํ์ จ๋ค๋ฉด manifest.xml์ ๋ฑ๋กํด์ผ ํฉ๋๋ค.
<application
android:name=".MyApplication"
...
4. ์์กด์ฑ ์ฃผ์ ๋ฐ๊ธฐ
์ฌ๊ธฐ๊น์ง ์ ๋ฐ๋ผ์ค์ จ๋ค๋ฉด ์ด์ ์์์ ๋ฑ๋กํ ๋ชจ๋์ ์ฃผ์ ๋ฐ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
by inject()๋ก Koin์ ๋ฑ๋ก๋ ๊ฐ์ฒด๋ฅผ lazy ํ๊ฒ ์ฃผ์ ๋ฐ์ ์ ์์ต๋๋ค.
์ฌ์ฉํ๊ณ ์ ํ๋ Activity ํด๋์ค์์ SampleController๋ฅผ ์ฃผ์ ๋ฐ์ ๋ด ์๋ค.
class SampleActivity : AppCompatActivity() {
โ
val controller: SampleController by inject()
โ
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate()
}
}
ํ ์ค์ด๋ฉด ๋ฉ๋๋ค. ์์ฃผ ๊ฐ๋จํ์ฃ ?
ViewModel์ ๊ฒฝ์ฐ by viewModel() ํค์๋๋ฅผ ์ฌ์ฉํฉ๋๋ค.
val viewModel: SampleViewModel by viewModel()
๊ฐ๋จํ๋ค๊ณ ๋งํ๊ณ ์์ง๋ง ๊ธฐ์กด์ ์ฌ์ฉํ๋ ๊ฒ์ ๋ฒ๋ฆฌ๊ณ ์๋ก์ด ๊ฒ์ ๋ฐฐ์ฐ๋ ๊ฒ์ ์ฝ์ง ์๊ณ ์กฐ๊ธ ๋ ๋์ ํ๋ก์ ํธ์ ๊ฐ๋ฐ์๊ฐ ๋๊ธฐ ์ํด์๋ ํ์ํ ๋ถ๋ถ์ด ‘์ฝ์ง๐ ’ ์ด๋ผ๊ณ ์๊ฐํด์.
์์ง ๋ง์ด ๋ถ์กฑํ๊ณ ์์ฑํ๋ฉด์๋ ๋ ๊ณต๋ถ๊ฐ ํ์ํ ๋ถ๋ถ์ด ์๋ค๊ณ ์๊ฐํด์ ๋ค์ ๊ธ์์๋ ์ ์ฉํ๋ฉด์ ๊ฒช์๋ ์ผ๋ค๊ณผ ์ฌ๋ฌ๊ฐ์ง ์ ์ฉ์ ํ์ํ ๊ฒ๋ค์ ์ ์ ์์ ์ ๋๋ค.
'Development > Android' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๐ฆย Databinding์ ์ฐ๋ฉด์ - 2 (0) | 2022.09.08 |
---|---|
๐ฆย Databinding์ ์ฐ๋ฉด์ - 1 (0) | 2022.09.08 |
์์กด์ฑ ์ฃผ์ ์ Koin๐ชย ๋ ๋ข์ - 2 (0) | 2022.09.08 |
Event Bus๐์ ๋ฒ์ค ์ข ๋ฐ์๋ณผ๊น? (0) | 2022.09.04 |
๋ฆฌ์์ค ๊ด๋ฆฌ (0) | 2022.09.04 |