본문으로 바로가기

SPRING의 DI를 나만 이해하기쉽게..

category Programing/JAVA 2023. 7. 28. 17:48
반응형

Spring의 Dependency Injection (DI)는 코드 간의 결합도를 낮추고, 유닛 테스트를 용이하게 만들며, 코드의 재사용성과 유지 보수성을 높이는 데 도움이 되는 설계 패턴입니다. DI의 핵심 아이디어는 "객체가 자신이 필요로 하는 의존성을 직접 생성하거나 찾는 대신 외부에서 받아서 사용한다"입니다.

이해를 돕기 위해, 우선 DI 없이 의존성을 관리하는 방법을 살펴봅시다. 아래 예제를 보겠습니다:

public class TextEditor {
    private SpellChecker checker;

    public TextEditor() {
        this.checker = new SpellChecker(); // TextEditor가 직접 SpellChecker를 생성
    }
}

여기서 TextEditor 클래스는 SpellChecker에 의존하고 있습니다. TextEditor는 직접적으로 SpellChecker의 객체를 생성하고 있습니다. 이런 설계는 다음과 같은 문제점을 가지고 있습니다:

TextEditor가 SpellChecker와 강하게 결합되어 있어, 다른 종류의 스펠체커를 사용하려면 TextEditor 코드를 변경해야 합니다.
테스트하려면 실제 SpellChecker를 사용해야 하므로, 테스트가 복잡해집니다.
이제 같은 상황에서 DI를 적용한 경우를 살펴보겠습니다:

public class TextEditor {
    private SpellChecker checker;

    public TextEditor(SpellChecker checker) { // 외부에서 SpellChecker를 주입받음
        this.checker = checker;
    }
}

이 경우 TextEditor는 여전히 SpellChecker를 필요로 하지만, 이제는 SpellChecker의 구체적인 인스턴스를 직접 생성하지 않습니다. 대신, 생성자를 통해 SpellChecker의 인스턴스를 주입 받습니다. 이 방법은 다음과 같은 이점이 있습니다:

TextEditor와 SpellChecker 간의 결합도가 낮아져 다른 스펠 체커를 사용하고 싶다면, 그저 다른 SpellChecker의 인스턴스를 주입하면 됩니다.
테스트가 더 쉬워집니다. 테스트를 위해 SpellChecker의 Mock 객체를 주입하면 됩니다.
Spring에서는 이런 DI를 자동으로 수행해주는 기능을 제공합니다. Spring 컨테이너는 @Autowired, @Inject 등의 애너테이션을 이용해서 어떤 의존성이 필요한지 파악하고, 이 의존성들을 생성해서 주입해줍니다. 이런 과정을 통해 우리는 의존성 관리에 대한 부담을 줄이고, 더 효율적인 코드를 작성할 수 있게 됩니다.

==== 결합도란?

결합도(Coupling)는 소프트웨어 개발에서 두 모듈 혹은 두 클래스 간의 상호 의존성을 나타내는 지표입니다. 즉, 한 컴포넌트가 다른 컴포넌트의 내부 작업에 얼마나 의존하고 있는지를 나타냅니다.

결합도가 높으면 두 컴포넌트는 서로 강하게 연결되어 있으며, 한 컴포넌트에서의 변경이 다른 컴포넌트에도 영향을 미칠 확률이 높아집니다. 이렇게 되면 유지 관리와 코드의 재사용이 어려워집니다.

예를 들어, 클래스 A가 클래스 B의 특정 메소드를 직접 호출하고 그 메소드의 반환값에 의존하는 경우, 이 두 클래스는 높은 결합도를 가지게 됩니다. 이 상황에서 클래스 B의 메소드를 변경하면, 클래스 A도 영향을 받아 변경해야 할 수 있습니다.

반대로, 결합도가 낮으면 두 컴포넌트는 독립적으로 동작할 수 있으며, 한 컴포넌트에서의 변경이 다른 컴포넌트에 영향을 미치는 확률이 줄어듭니다. 이렇게 되면 코드의 유지 관리와 재사용이 용이해집니다.

예를 들어, 클래스 A와 B가 인터페이스 C를 통해서만 상호작용하는 경우, 클래스 A와 B의 결합도는 낮아집니다. 이 경우 클래스 B의 내부 구현이 변경되더라도, 인터페이스 C가 동일하다면 클래스 A는 변경할 필요가 없습니다.

소프트웨어 개발에서는 일반적으로 결합도를 최대한 낮추는 것이 바람직하다고 간주됩니다. 이를 위해 디자인 패턴, 모듈화, 인터페이스 및 추상화 등의 기법이 사용됩니다. 이 중 하나가 위에서 언급한 Dependency Injection 패턴입니다. 의존성 주입을 사용하면 구체적인 클래스 대신에 인터페이스에 의존함으로써, 결합도를 낮출 수 있습니다.

반응형