[Spring] DI(Dependency Injection)

·2022년 10월 17일
0

Spring

목록 보기
8/24
post-thumbnail
post-custom-banner

📝 DI와 DIP 에 추가적으로 학습한 내용

DI

: 의존성 주입, IoC의 원칙(역제어)을 구현하기 위해 사용되는 방법 중 하나

DI(Dependency Injection)의 역할

💡 A클래스는 B클래스와 C클래스의 객체를 필요로 한다면

1. A클래스 내부에서 객체를 직접 생성

  • DI를 학습하기 전이라면 이러한 문제를 마주했을 때 하는 방법은 A클래스 내부에서 B와 C의 객체를 직접 생성 하여 사용하였을 것이다.
class A {
	B b = new B();
    C c = new C();
}
  • 직접 객체를 생성하는 것의 문제점은❓
    • 응집도가 높고 결합도가 낮을수록 객체지향적인 설계라고 한다.
    • new연산자를 이용해 직접 객체를 생성할 경우, A클래스가 B,C객체에 강한 의존 관계가 성립된다.
    • 강한 의존 관계로 인해 추후에 코드에 문제가 발생하여 유지 보수가 어렵다.

💡응집도와 결합도

  • 응집도 : 모듈에 포함된 내부 요소들이 연관되어 있는 정도
    하나의 변경을 수용하기 위해 모듈 전체가 함께 변경 -> 응집도가 높은 것
  • 결합도 : 의존성의 정도, 다른 모듈에 대해 얼마나 많이 관여하고 있는지에 대한 척도
    다른 모듈에 대해 자세히 알수록 결합도가 높은 것 -> 서로 연관되어 있기 때문에 결합도가 높을 수록 변경 사항을 수용하기 어렵다.

    객체지향적 설계의 목표😠👊
    코드의 재사용성, 원활한 유지보수(변경 용이), 중복된 코드 제거

2. 외부에서 생성된 객체를 받아와서 사용

class A {
	B b;
    C c;
    
    // 생성자를 통해 주입
    public A(B b) {
    this.b = b;
    }
    public A(C c) {
    this.c = c;
    }
}
  • 외부로부터 이미 생성된 객체를 가져와서 사용함(의존성 주입)으로서 코드의 재사용성을 높이고 중복코드를 없앨 수 있는 장점이 있다.

예시. 카페 손님이 주문을 한다면?

  1. 1번의 상황일 때,

  • MemberService에서 생성된 MemberRepository로 카페 손님의 이름과 주문이 저장되었고, 저장된 내역에 따라 주문 받은 것을 손님에게 주어야 하는데 OrderService에 생성된 MemberRepositoryMemberService에서 생성된 것과 달라 주문 내역이 저장되어 있지 않다.
  • 같은 MemberRepository를 사용하지 않고 각각 별도의 객체를 생성하여 여러가지 문제가 발생할 수 있다.
  1. 2번의 상황일 때,

  • 외부에서 생성된 객체가 주입되어 사용되기 때문에 같은 MemberRepository를 사용할 수 있고 추후에 MemberRepository에 문제가 발생하더라도 MemberRepository의 파일만 변경하면 되므로 유지보수가 상대적으로 쉽다.

DI의 방법

: 의존성을 주입하는 방법에는 4가지 방법이 존재한다.

  • 생성자 주입 -> 가장 권장하는 방법
  • 수정자(setter) 주입
  • 필드 주입
  • 일반 메서드 주입

생성자 주입

  • 생성자에 @Autowired어노테이션을 입력하는 방법
  • 생성자가 1개만 존재하는 경우 @Autowired어노테이션을 생략할 수 있다.
@Component
public class CoffeeService {
  private final MemberRepository memberRepository;

  @Autowired
  public OrderServiceImpl(MemberRepository memberRepository, {
    this.memberRepository = memberRepository;
  }
}

수정자 주입

  • setter 메서드를 작성 후 @Autowired어노테이션을 입력하는 방법
  • 생성자 주입과 달리 @Autowired어노테이션 생략 불가
  • 😠치명적 단점 : set값(변경되지 않아야 하는 값)이 퍼블릭하게 노출될 수 있다.

필드 주입

  • 필드에 @Autowired어노테이션을 입력하는 방법
  • 단점 필드의 값을 변경할 수 없음

일반 메서드 주입

  • 일반 메서드에 @Autowired어노테이션을 입력하는 방법
  • 일반적으로 사용되지 않는다.

💡생성자 주입을 권장하는 이유
1. 생성자는 객체를 생성할 때 단 한번만 호출되므로 종료 전까지 변경될 일이 없다.
2. 의존성 주입이 필요한 필드를 final로 선언할 수 잇따.
3. 테스트 코드 작성이 용이하다.
4. 순환 참조를 방지할 수 있다.

profile
🧑‍💻백엔드 개발자, 조금씩 꾸준하게
post-custom-banner

0개의 댓글