Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
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
Tags
more
Archives
Today
Total
관리 메뉴

개발자이야기

의존성주입(DI) android dagger 본문

android

의존성주입(DI) android dagger

개발자가되고싶어 2021. 5. 22. 01:51
해당 글은 kotlin을 기반으로 작성 되었습니다.

 

의존성 주입(DI)이란 무엇일까?

 

간단하게 객체를 외부에서 생성하여 넘겨주는 것을 말한다.

class Car {

    var engine: Diesel = Diesel()
    var tier: SnowTier = SnowTier()

    fun engineStart() {
        engine.start()
    }
}

위의 코드를 보자 Car 클래스에 Diesel 엔진과 SnowTier 라는 타이어가 있다.

뭐 대충 이래도 자동차에 엔진과 타이어가 달렸으니 문제는 없겠지만

이와같이 작성한다면 Car 클래스에 Diesel 클래스 와 SnowTier 클래스 객체에 대한 의존성이 생긴 것 이다.

그냥 이렇게 써도 된다. 문제는 없다. 실제 자동차 였다면 디젤 엔진을 달고 스노우 타이어로 잘 달렸을 것이다.

하지만 유지보수 측면에서는 좋지 않다. 만약 Car 클래스를 인스턴스화 해서 사용한다면

해당 자동차는 Diesel 엔진과 SnowTier를 강제적으로 사용해야 한다.

물론 교체하여 사용해도 되겠지만 이곳저곳에서 사용한다면..?? 꽤나 머리아픈 일이 발생할 수 있다.

그만큼 유지보수가 용이하지 못하며 유연하지 못한 코드가 된다.

 

class Car {

    var engine: Engine? = null
    var tier: Tier? = null

    constructor(engine: Engine, tier: Tier) {
        this.engine = engine
        this.tier = tier
    }

    fun engineStart() {
        engine?.start()
    }
}

좀더 개선을 해보자

위와같이 Car 클래스의 생성자에 외부에서 Engine 과 Tier를 넘겨줌으로써 Car 클래스에서 

Diesel 과 SnowTier 클래스 객체의 의존성은 사라졌다 

 

class Gasoline: Engine {
    override fun engine(): String {
        return "가솔린엔진"
    }
}

class SnowTier: Tier {
    override fun tier(): String {
        return "겨울타이어"
    }
}

여기서 Engine 과 Tier 는 interface 이다 외부에서 구체화된 객체를 생성자를 통해 넘겨주겠다는 것이다.

코틀린으로 간단하게 설명을 위한 예제이니 위의 코드는 양해 부탁드립니다.

 

하지만 이글은 android Dagger를 위한 글이니 Dagger를 사용해보자

 

해당 글에서는 의존성 주입의 설명과 그것을 Dagger로 바뀌는 코드만을 작성합니다.

Dagger의 자세한 사용법은 다른 블로그를 참고해 주시기 바랍니다.

@Module
class CarModule {

    @Provides
    fun provideEngine(): Engine {
        return LPG()
    }

    @Provides
    fun provideTier(): Tier {
        return SummerTier()
    }
}

주입 시켜줄 모듈을 작성하여 구체화된 객체를 의존성 주입 해준다.

 

class Car @Inject constructor() {

    @Inject lateinit var engine: Engine
    @Inject lateinit var tier: Tier

    fun engine(): String {
        return engine.engine()
    }

    fun tier(): String {
        return tier.tier()
    }
}

위에서 주입시켜준 LPG 엔진과 SummerTier 타이어가 주입되었다!

이제 Car객체 에선 더이상 어떤 구체화된 Engine이 들어와도 상관이 없으며 Engine, Tier 의 구체화된 객체의 수정이 일어나도 Car 객체는 더이상 수정할 필요가 없다

 

만약 Car1 객체에서는 여름 타이어를 사용하고 Car2 객체에서는 겨울 타이어를 사용하고 싶을 수 있다.

 

@Module
class CarModule {

    @Provides
    fun provideEngine(): Engine {
        return LPG()
    }

    @Provides
    fun provideTier(): Tier {
        return SummerTier()
    }

    @Provides
    @Named("겨울타이어")
    fun provideSnowTier(): Tier {
        return SnowTier()
    }
}
class Car @Inject constructor() {

    @Inject lateinit var engine: Engine
    @Inject @Named("겨울타이어") lateinit var tier: Tier

    fun engine(): String {
        return engine.engine()
    }

    fun tier(): String {
        return tier.tier()
    }
}

그럼 위와같이 @Named를 사용하여 리턴할 객체를 지정해줄 수 있다.

 

소스는 여기에 https://github.com/boidmy/androidDagger

 

의존성 주입에 관해선 아직도 계속 공부하는 중입니다.

이글은 많이 부족할수도 있는 글입니다. 공부한 것을 토대로 작성한 것이니 언제든 개선점 지적 환영합니다.

'android' 카테고리의 다른 글

mvvm + dagger  (0) 2021.06.07
android AAC LiveData - switchMap, map  (0) 2021.05.28
dagger @binds 어노테이션  (1) 2021.05.23
android recyclerview diffutil  (0) 2021.05.14
Retrofit2 url이 만들어지는 패턴  (0) 2020.06.02