Android 공부/DI ( 의존성 주입 )

[Android] DI ??

Machine_웅 2022. 4. 18. 21:04
728x90
반응형

1. DI ( 그게 뭔데..왜 날 괴롭히는거야 )

- Dependency Injection ( 의존관계 주입 )

“A가 B를 의존한다.”는 표현은 =>  B의 기능이 추가 또는 변경되거나 형식이 바뀌면, 그 영향이 A에 미친다.

 

1) 의존관계??? 그건 뭔데 

예시)  

햄버거 가게 요리사는 햄버거 레시피에 의존한다. 햄버거 레시피가 변화하게 되었을 때,

변화된 레시피에 따라서 요리사는 햄버거 만드는 방법을 수정해야 한다.

레시피의 변화가 요리사의 행위에 영향을 미쳤기 때문에, 

“요리사는 레시피에 의존한다”고 말할 수 있다. 코드로 표현해보면 다음과 같다.

class BurgerChef {
    private HamBurgerRecipe hamBurgerRecipe;

    public BurgerChef() {
        hamBurgerRecipe = new HamBurgerRecipe();        
    }
}

 

1 - 1) 의존관계를 인터페이스로 추상화하기

위 BurgerChef 예시를 보자.

지금의 구현에서는 HamBurgerRecipe만을 의존할 수 있는 구조로 되어있다.

더 다양한 BurgerRecipe를 의존 받을 수 있게 구현하려면

 인터페이스로 추상화해야 한다.

다음의 코드에서 볼 수 있듯이, 다양한 버거들의 레시피에 의존할 수 있는 BurgerChef가 된다.

 

class BurgerChef {
    private BurgerRecipe burgerRecipe;

    public BurgerChef() {
        burgerRecipe = new HamBurgerRecipe();
        //burgerRecipe = new CheeseBurgerRecipe();
        //burgerRecipe = new ChickenBurgerRecipe();
    }
}

interface BugerRecipe {
    newBurger();
    // 이외의 다양한 메소드
} 

class HamBurgerRecipe implements BurgerRecipe {
    public Burger newBurger() {
        return new HamBerger();
    }
    // ...
}

( * 의존관계를 인터페이스로 추상화하게 되면, 더 다양한 의존 관계를 맺을 수가 있고,

실제 구현 클래스와의 관계가 느슨해지고, 결합도가 낮아진다. )

 

2) 그럼 DI (Dependency Injection ) 의존관계 주입은 뭔데?

 

위에 예시에서는 BurgerChef 내부적으로 의존관계인 BurgerRecipe가 어떤 값을 가질지 직접 정하고 있다.

만약 어떤 BurgerRecipe를 만들지를 버거 가게 사장님이 정하는 상황을 상상해보자.

즉, BurgerChef가 의존하고 있는 BurgerRecipe를 외부(사장님)에서 결정하고 주입하는 것이다.

 

 그 의존관계를 외부에서 결정하고 주입하는 것이 DI(의존관계 주입)이다.

 

 

의존관계 주입이란, 세 가지 조건을 충족하는 작업을 말한다.

  1. 클래스 모델이나 코드에는 런타임 시점의 의존관계가 드러나지 않는다. 그러기 위해서는 인터페이스에만 의존하고 있어야 한다.
  2. 런타임 시점의 의존관계는 컨테이너나 팩토리 같은 제3의 존재가 결정한다. (NConnectoinMaker 혹은 DConnectionMaker 선택)
  3. 의존관계는 사용할 오브젝트에 대한 레퍼런스를 외부에서 제공해줌으로써 만들어진다.

의존관계 주입의 핵심은 설계 시점에는 알지 못했던 두 오브젝트의 관계를 맺도록 도와주는 제3의 존재가 있다는 것이다.

  • DI에서 말하는 제 3의 존재는 전략 패턴에서 등장하는 클라이언트나 DaoFactory, 또는 DaoFactory 같은 작업을 일반화해서 만들어진 애플리케이션 컨텍스느, 빈 팩토리, IoC 컨테이너 등이 모두 외부에서 오브젝트 사이의 런타임 관계를 맺어주는 책임을 지닌 제3의 존재이다.

2. DI 구현 방법

DI는 의존관계를 외부에서 결정하는 것이기 때문에,

클래스 변수를 결정하는 방법들이 곧 DI를 구현하는 방법이다.

런타임 시점의 의존관계를 외부에서 주입하여 DI 구현이 완성된다.

 

    Burger 레스토랑 주인이 어떤 레시피를 주입하는지 결정하는 예시로 설명하고자 한다.

  • 생성자를 이용
class BurgerChef {
    private BurgerRecipe burgerRecipe;

    public BurgerChef(BurgerRecipe burgerRecipe) {
        this.burgerRecipe = burgerRecipe;
    }
}

class BurgerRestaurantOwner {
    private BurgerChef burgerChef = new BurgerChef(new HamburgerRecipe());

    public void changeMenu() {
        burgerChef = new BurgerChef(new CheeseBurgerRecipe());
    }
}
  • 메소드를 이용 (대표적으로 Setter 메소드)
class BurgerChef {
    private BurgerRecipe burgerRecipe = new HamburgerRecipe();

    public void setBurgerRecipe(BurgerRecipe burgerRecipe) {
        this.burgerRecipe = burgerRecipe;
    }
}

class BurgerRestaurantOwner {
    private BurgerChef burgerChef = new BurgerChef();

    public void changeMenu() {
        burgerChef.setBurgerRecipe(new CheeseBurgerRecipe());
    }
}

3. 장점 ( 그래서 쓰면 뭐가 좋은데 )

1. 의존성이 줄어든다.

앞서 설명했듯이, 의존한다는 것은 그 의존대상의 변화에 취약하다는 것이다.

(대상이 변화하였을 때, 이에 맞게 수정해야함) DI로 구현하게 되었을 때,

주입받는 대상이 변하더라도 그 구현 자체를 수정할 일이 없거나 줄어들게됨.

 

2. 재사용성이 높은 코드가 된다.

기존에 BurgerChef 내부에서만 사용되었던 BurgerRecipe을 별도로 구분하여 구현하면,

다른 클래스에서 재사용할 수가 있다.

 

3. 테스트하기 좋은 코드가 된다.

BurgerRecipe의 테스트를 BurgerChef 테스트와 분리하여 진행할 수 있다.

 

4. 가독성이 높아진다.

BurgerRecipe의 기능들을 별도로 분리하게 되어 자연스레 가동성이 높아진다.

 


정리

DI(의존관계 주입)는 객체가 의존하는 또 다른 객체를 외부에서 선언하고 이를 주입받아 사용하는 것이다.

이를 구현함으로써 얻을 수 있는 장점들을 알아봤다.

 

 

 

출처 : 

https://tecoble.techcourse.co.kr/post/2021-04-27-dependency-injection/

 

의존관계 주입(Dependency Injection) 쉽게 이해하기

이번 글에서는 DI(의존성 주입, 의존관계 주입)의 개념을 설명한다.

tecoble.techcourse.co.kr

 

 

추가 참고

https://kotlinworld.com/64

 

의존성 주입이란 무엇이며 왜 필요한가?

목표 의존성 주입이 무엇인지 이해한다. 의존성 주입이 왜 필요한지 이해한다. 의존성 주입이란?  의존성 주입이란 클래스간 의존성을 클래스 외부에서 주입하는 것을 뜻한다.  더 자세하게는

kotlinworld.com

 

728x90
반응형

'Android 공부 > DI ( 의존성 주입 )' 카테고리의 다른 글

Hilt ?  (0) 2022.05.16
DI ) Dagger2의 5가지 필수 개념  (0) 2022.04.26
DI ) Dagger2 란?  (0) 2022.04.25
[Android] DI Framework (Dagger2, Koin, Hilt)  (0) 2022.04.18