의존성(Dependency)과 의존성 주입(DI)

May Han·2022년 2월 7일
2

의존성(Dependency)이란?

  • 의존성, 종송석을 의미한다.
  • 코드에서 두 모듈(클래스)간의 연결 혹은 관계를 말한다.
  • 클래스 A가 다른 클래스 B를 이용할 때 A가 B에 의존한다고 한다. 이런 관계에서 A는 B없이 작동할 수 없다.
  • 의존 대상 B가 변하면, 그것이 A에 영향을 미친다. (토비의 스프링에서의 정의)

💡 의존성은 저수준에서 고수준 정책을 향해야 한다.
구체적인 것이 추상화된 것에 의존해야 한다.

  • 고수준 : 상위 수준의 개념, 추상화된 개념
  • 저수준 : 추상화된 개념을 실제 어떻게 구현할지에 대한 세부적인 개념



의존성(Dependency)을 지양하는 이유

  • 높은 의존성은 모듈의 재사용을 감소시킨다.
  • 하나의 모듈이 바뀌면 의존한 다른 모듈까지 변경이 이루어진다.
  • 테스트 가능한 어플을 만들 때 의존성이 있으면 유닛테스트 작성이 어렵다.



의존성 주입(Dependency Injection)이란?

  • 여기에서 '주입'이란 외부에서 객체를 생성해서 넣어주는 것을 뜻한다.
  • 즉, 객체가 의존하는 또 다른 객체를 외부에서 선언하고 이를 주입하는 것이 의존성 주입(DI)이다.
  • 의존성 주입은 하나의 패턴으로 의존성들을 인자들로 전달해준다면 모듈안에서 의존성들을 불러오거나 새로 만드는 것을 피할 수 있다.
  • IoC의 대표적인 구현 방식이다. (IoC와 DI는 다르다)

💡 IoC(Inverse of Control)
제어권을 개발자가 아닌 제3자(framework)가 가지게 하는 것이다. IoC의 주된 목적은 Application의 Dependency를 제거해서 느슨한 결합(loose coupling)을 제공하는 것이다.

✍ 토비의 스프링에서는 다음 조건을 충족하는 작업을 의존성 주입이라고 말한다.
1. 클래스 모델이나 코드에는 런타임 시점의 의존관계가 드러나지 않는다. 그러기 위해서는 인터페이스만 의존하고 있어야 한다.
2. 런타임 시점의 의존관계는 컨테이너나 팩토리 같은 제3의 존재가 결정한다.
3. 의존관계는 사용할 오브젝트에 대한 레퍼런스를 외부에서 제공(주입)해줌으로써 만들어진다.



의존성 주입(DI)의 이점

1. 의존성이 줄어든다.
의존한다는 것은 의존 대상이 변하면 의존하는 곳에서도 이에 맞게 수정을 해줘야하는 일이 생긴다. 하지만 DI로 구현하게 된다면 주입 받는 대상이 변하더라도 그 구현 자체를 수정할 일이 없거나 줄어들게 된다.

2. 재사용성이 높은 코드가 된다.
내부에서만 사용되던 의존 대상 클래스(모듈)를 독립적으로 구현하여 다른 클래스에서도 재사용할 수 있게 한다.
즉, 결합도(coupling)는 낮추면서 유연성과 확장성은 향상시킬 수 있다.

3. 테스트하기 좋은 코드가 된다.
다른 클래스와 독립적으로 클래스를 테스트 할 수 있습니다.

4. 가독성이 높아진다.
기능들을 별도로 분리하게 되어 자연스럽게 가독성이 높아진다.



의존성 주입(Dependency Injection) 방법

기록을 위해 참고한 블로그에서 일부 코드만 가져왔다. 전체 내용을 확인하려면 여기를 확인해보자.

1. Contructor Injection : 생성자 삽입

public class MemberService {
    private final JsonParser jsonParser;

	// 생성자를 통해 의존성을 주입 받는다. 
    public MemberService(JsonParser jsonParse) {
        this.jsonParser = jsonParse;
    }
}

// 사용자는 다음과 같이 주입한다. 
public static void main(String [] args) {
    JsonParser parser = new JacksonParser(); // Gson으로 바뀌더라도 MemberService의 구현은 바꿀 필요가 없다. 

    //Constructor Injection
    MemberService memberService = new MemberService(parser);
}



2. Method Injection : 메소드 매개 변수 삽입

대표적으로 Setter 메소드를 사용한다.

public class MemberService {
    private JsonParser jsonParser;

    // Setter 함수의 매개변수로 의존성을 주입 받는다. 
    public void setJsonParser(JsonParser jsonParser) {
        this.jsonParser = jsonParser;
    }
}

// 사용자는 다음과 같이 주입한다. 
public static void main(String [] args) {
    JsonParser parser = new JacksonParser(); // Gson으로 바뀌더라도 MemberService의 구현은 바꿀 필요가 없다. 

 	//Setter Injection
    memberService = new MemberService();
    memberService.setParser(parser);
}




Reference

profile
🚢 크루즈승무원 출신 백엔드 개발자, 기록하는 것을 좋아합니다.

1개의 댓글

comment-user-thumbnail
2024년 3월 26일

감사합니다:)

답글 달기