일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- DataBinding
- Di
- Status Bar
- 군대 github
- Encoding
- 군대개발
- android studio cloud
- android 오류
- okhttp
- Compose
- interface
- REST API
- 오류
- Android
- 네트워크
- 군대 깃허브
- 디버깅 오류
- log
- intArray
- 군대 개발
- RETROFIT
- BindingAdapter
- 군대에서 안드로이드 개발
- Rest
- 뷰 겹침
- text
- kotlin
- Log잘림
- multipart
- apollo
- Today
- Total
KDY
DI? Dependency Injection란 무엇일까? 본문
개발을 진행하다 보면 DI를 많이 들어봅니다.
그렇다면 이 DI? 도대체 무엇일까요? 그래서 오늘은 DI에 대해 알아볼 것입니다.
DI란?
Dependency Injection의 줄임말로 Dependency(의존성) Injection(주입)입니다.
의존성 주입은 하나의 객체가 다른 객체의 의존성을 제공하는 기술입니다. 비유하자면 '의존성'은 서비스로 사용할 수 있는 객체이고 '주입'은 의존성(서비스)을 사용하려는 객체로 전달하는 것을 의미합니다. DI는 프로그래밍에 널리 사용되는 기법으로, DI의 원칙을 따르면 훌륭한 앱 아키텍처를 위한 토대를 마련할 수 있습니다.
예를 한 번 들어보겠습니다.
저희 집이 이불가게를 하므로 이불가게로 예를 들어보겠습니다.
//이불가게 업무 클래스
class QuiltShopTask{
fun orderQuilt() //이불 재고를 주문하는 함수
}
//이불가게 사장님 클래스
class Owner{
val quiltTask = QuiltShopTask()
fun work(){
quiltTask.orderQulit()
}
}
위처럼 이불가게 업무(QuiltShopTask) 클래스가 있고, 이불가게 사장님(Owner) 클래스가 있습니다.
이때 Owner클래스에 QuiltShopTask의 요소(orderQuilt)가 있습니다. 이때 이관계가 의존관계이고
정확히는 Owner가 QuiltShopTask에 의존하고 있다고 할 수 있습니다.
이처럼 한 요소에(Owner)에 다른 객체의 요소(QuiltShopTask)가 한 번 등장하면, 그 뒤로 그 객체는(QuiltShopTask) 없어지면 안 됩니다. 예를 들어, 의존 대상인 QuiltShopTask 클래스가 사라지면, Owner객체는 바로 컴파일이 불가능해지고 동작할 수 없는 상태가 됩니다. 그래서 이런 관계를 "의존"이라고 부릅니다.
만역 이불가게 사장님이 업종을 음식점으로 바꿨다면 코드를 다음같이 바꿔야 합니다.
class restaurantTask{
fun orderIngredient()
}
class Owner{
val restaurantTask = restaurantTask()
fun work(){
restaurantTask.orderIngredient()
}
}
지금은 하나의 요소(orderInredient)만을 사용하기 때문에 그렇게 불편 하지는 않습니다. 하지만 요소가 많다면?
일일이 하나씩다 바꿔야 하는 일 이 발생할 수 있습니다. 이는 곧 코드의 재사용성과 유연성을 떨어트리게 되어 코드의 유지보수를 어렵게 하는 원인이 됩니다.
Dependency injection 이란?
interface StoreTask{
fun order ()
}
class QuiltTask : StoreTask{
override fun order() { //이불 주문하는 코드}
}
class resturantTask : StoreTask{
override fun order() { //음식재료 주문하는 코드}
}
class Owner(task : StoreTask){
private var task = StoreTask()
init{
this.task = task //Owner안의 task변수와 StorTask Type의 task 연결
}
fun changeStore(newStoreTask : StoreTask) {
this.task = newStoreTask //현재 task를 새로운 task로 변경
}
fun work(){
task.order()
}
}
fun main(args: Array<String>) {
//초기 이불가게를 운영하시는 사장님
val owner = Owner(QuiltStoreTask())
// 음식점으로 직종을 변경하신 사장님
owner.changeStore(resturantTask())
}
위와 같이 의존하는(필요한) 클래스를 직접 생성하는 것이 아니라, 생성자와 메서드를 통해 외부에서 주입해줌으로써 객체 간의 결합도를 줄이고 좀 더 유연한 코드를 작성할 수 있게 되었습니다. 이제 사장님이 이불가게나 음식점으로 업종을 변경해도, StoreTask 인터페이스를 구현한 이불가게 클래스나 음식점 클래스를 만들어 사용하기만 하면 됩니다.
Android에서는 Dagger,Hilt,Koin등의 프레임워크를 사용하여 간단하게 만들 수 있습니다.