# DI, (Dependency Injection)

## DI (Dependency Injection, 의존성 주입)

> 객체지향 프로그래밍에서 **의존성 관리를 위한 디자인 패턴**
>
> 객체가 다른 객체에 의존하지 않도록 **외부에서 주입 받는 형태**로 사용하는 것

<figure><img src="https://1912740209-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3GVYdZvmqQyBVq29ebqk%2Fuploads%2FUz56z26vRdkoGDpNsQDV%2FDI_explain.webp?alt=media&#x26;token=b2ef2242-1806-4133-90f1-a3d2232725fd" alt=""><figcaption></figcaption></figure>

의존성 주입이란 외부에서 **의존 객체를 생성하여 넘겨주는 것**을 의미

의존성을 외부에서 주입 받아 의존성을 없애고 객체간 **결합도를 낮춘다.**

### 의존성을 주입하는 세가지 유형

* **Constructor Injection** → 클래스 생성자를 통해 의존성 주입
* **Method(Setter) Injection** -> 객체(클래스) 생성 후 메서드를 통해 의존성을 주입
* **Interface Injection** -> 종속성을 주입할 메서드를 갖는 인터페이스를 이용하여 의존성을 받을 클래스(객체가) 구현하도록 주입하는 방식

### DI 장점&#x20;

* 의존 객체를 갈아 끼울 수 있어 재사용성과 확장성 높아진다.
* 외부의 의존 객체를 Mock 으로 대체하여 단위 테스트 작성이 쉬워진다.
* 다른 객체에 의존하지 않아서 코드가 변경이 되어도 다른 객체에 영향을 덜 주므로 유연한 코드를 작성할 수 있다.

{% hint style="info" %}
**유연한 코드란?**

* 변경이나 확장에 대해서 유연하게 대처할 수 있는 코드를 의미한다.&#x20;
* 유지보수성 👍, 확장성 👍&#x20;
* 유연한 코드를 작성하려면 코드 간 결합도가 낮아야 한다.
  {% endhint %}

### DI Container

> DI를 구현하기 위해 객체 생성, 의존성 주입 등을 자동으로 처리해주는 외부 역할

DI Container를 일반적으로 **Context**, 또는 **Container**라고 부른다.

가장 대표적인 DI Container는 Spring Framework

## IoC (Inversion of Control, 제어의 역전)

> **의존성을 제거하기 위한 객체지향 설계 원칙**\
> **DI Pattern은 IoC를 구현하는 대표적인 방법**

<figure><img src="https://1912740209-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3GVYdZvmqQyBVq29ebqk%2Fuploads%2FKOLBwbCkclGIxKbAGGvO%2Fioc-patterns.webp?alt=media&#x26;token=4c0b3115-4f9e-46d9-bf2b-ca8f4ce105b8" alt=""><figcaption></figcaption></figure>

제어의 역전을 간단히 설명하자면 **프로그램의 실행 흐름의 제어권을 외부(프레임워크)에게 위임하는 것!**

{% hint style="info" %}
객체지향 프로그래밍 설계의 기본 원칙SOLI**D 의 다섯 번째 원칙 Dependency Inversion**\
"낮은 수준의 구현에 의존하지 말고 높은 수준의 추상화에 의존해야 한다는 뜻"

[Dependency Inversion vs Dependency Injection](https://medium.com/better-programming/straightforward-simple-dependency-inversion-vs-dependency-injection-7d8c0d0ed28e)
{% endhint %}

{% hint style="info" %}
**Why do we call it Dependency “Inversion”?**

Well, it appears that in traditional software development, the best practice was to build software in a layered architecture, which enabled the construction of increasingly complex systems.

In this architecture, higher-level components depended directly upon lower-level components in order to achieve a complex task.
{% endhint %}
