DI는 중요해

2024. 5. 10. 21:01TIL

✔오늘 배운 중요한 🔑 point

  • DI를 활용함으로서 객체간의 결합도를 낮추고 이는 코드를 유연하게 만들고 재활용이 용이하게 만들어 준다

🎯 오늘 배운 내용

 

spring에서 매우 중요한 개념 중 하나인 DI 

DI는 Dependency Injection , 의존 관계 주입인데 , 외부에서 주입받는 디자인 패턴이다

 

그렇다면 DI가 왜 필요한지 알아보자!!

 

package di

class Playstation5 {

    private val playstation: Game= ActionGame()
    fun gameTitle(): Game {
        playstation.getName()
        return playstation
    }
}

fun main(args: Array<String>){
    val playStation5 = Playstation5()
    val gameTitle= playStation5.gameTitle()

}

 

자 Playstation5라는 class가 있다고 가정하자!  첫줄의 이 playstation 이라는 변수는  ActionGame()이라는 객체를 참조하고 ActionGame() 객체 안에 있는 함수인 getName()을 호출한다.

즉 이 Playstation5라는 class는 ActionGame()이라는 객체를 참조하고 함수를 호출하는 기능을 한다고 볼 수 있다.

그렇다면 여기서  ActionGame()이라는 class(객체) 말고 다른 class(객체)를 참조하고 불러오고싶다면 어떻게 해야할까?

여기서 다른 객체를 참조하고 불러오고 싶다면 하나의 class(객체)를 더 만들면 된다

package di

class Playstation5 {

    private val playstation: Game= ActionGame()
    fun gameTitle(): Game {
        playstation.getName()
        return playstation
    }
}

class Playstation52 {

    private val playstation: Game= RpgGame()
    fun gameTitle(): Game {
        playstation.getName()
        return playstation
    }
}

fun main(args: Array<String>){
    val playStation5 = Playstation5()
    val gameTitle= playStation5.gameTitle()

    val playStation52 = Playstation52()
    val gameTitle2 = playStation52.gameTitle()

}

단순히 class를 하나 더 추가하면  정상적으로 다른 class인 RpgGame안의 gameTitle()을 불러올 수 있다.

하지만 이런식으로 코드를 작성하게 된다면 결합도가 매우 높아서 class를 하나하나 따로 만들어줘야하는 번거로움이 생긴다.  예를들어 5개의 class를 참조하고싶다면 각각의 class를 참조하는 class를 따로 따로 5개를 더 만들어줘야 할것이다.

 

 

하지만 DI를 적용시킨다면??

 

package di

class Playstation5(private val game:Game) {

    fun gameTitle():Game{
        game.getName()
        return game
    }
}

fun main(args: Array<String>) {
    val action= ActionGame()
    val playstation5 = Playstation5(action)
    val gameTitle= playstation5.gameTitle()

    val rpg = RpgGame()
    val playstation52 = Playstation5(rpg)
    val rpgTitle = playstation52.gameTitle()
}

 

class Playstation5(private val game:Game)의 안에 있는 private val game:Game 를 통해

 결합도를 낮추고 외부에서 명시적으로 주입이 되어야한 다는것을 표기함으로서 훨씬 유연하게 코드 작성이 가능하며 재활용 가능성 또한 높아지는 효과를 볼 수 있다

 

위의 방식은 외부에서 주입받는 형태중 Constructor(생성자)를 통해 주입받는 형식인데 

초기에 class Playstation5(private val game:Game) 이렇게 인스턴스가 생성될때 초기에 의존성이 들어가 있기때문에 의존성이 불변한다는 것을 명시해주는 것이 개발자의 실수를 방지해주기도 하기 때문에 실제 협업에서도 가장 많이 사용되는 방식이다

 

IOC (제어의 역전?)

위 코드를 예시로 봤을때 val playstation5 = Playstation5(action) 에서 Playstation5 객체가 생성될때 우리가 action이라는 객체를 외부에서 주입했지만,  우리가 직접  의존성을 주입하는것이 아닌 프레임워크에서 대신 주입해주기 때문에 제어가 역전된다고 할 수 있다.

 

🤔 어떻게 활용할까?

생성자를 통한 DI는 실제 협업에서도 많이 사용된다고 하니 DI를 사용하는 방식에 많이 익숙해질 필요가 있다

📓 오늘의 한줄

"Some of the most beautiful things worth having in your life come wrapped in a crown of thorns."

- Hermann Hesse -

 

 

 

 

'TIL' 카테고리의 다른 글

RequestMapping 너는 내가 담당한다  (0) 2024.05.12
@Bean  (0) 2024.05.11
Swagger  (0) 2024.05.09
Tactical Design & REST API  (0) 2024.05.08
Spring이란  (0) 2024.05.07