의존
- 기능 구현을 위해 다른 구성 요소를 사용하는 것
- 의존의 예 : 객체 생성, 메서드 호출, 데이터를 사용
- 의존은 변경이 전파될 가능성을 의미
- 의존하는 대상이 바뀌면 바뀔 가능성이 높아짐
- 예 : 호출하는 메서드의 파라미터가 변경
- 예 : 호출하는 메서드가 발생할 수 있는 익셉션 타입이 추가
순환 의존
- 순환 의존 → 변경 연쇄 전파 가능성
- 클래스, 패키지, 모듈 등 모든 수준에서 순환 의존이 발생하도록 해야합니다.
의존하는 대상이 많다면?
의존 대상 많을 때 1 : 기능이 많은 경우
- 한 클래스에서 많은 기능을 제공하는 경우
- 각 기능마다 의존하는 대상이 다를 수 있음
- 한 기능 변경이 다른 기능에 영향을 줄 수 있음
- 특정 메소드를 테스트를 할 때 의존하지 않는 다른 대상도 초기화해야하기때문에, 테스트가 어려워짐
- 기능 별로 분리를 고려
- 클래스는 증가하지만 각 클래스는 의존하는 대상이 줄어들게 됨
- 한 기능 변경이 다른 기능에 영향을 주지 않음
- 개별 클래스를 테스트하기 쉬워짐
의존 대상이 많을 때 2 : 묶어 보기
- 몇 가지 의존 대상을 단일 기능으로 묶어서 생각하게 된다면 의존 대상을 줄일 수 있음
의존 대상 객체를 직접 생성하면?
- 생성 클래스가 바뀌면 의존하는 코드도 바뀌게 됨
- 의존 대상 객체를 직접 생성하지 않는 방법
- 팩토리, 빌더
- 의존성 주입 ( Dependency Injection )
- 서비스 로케이터
의존성 주입 ( Dependecy Injection )
- 외부에서 의존 객체를 주입
- 생성자나 메서드를 이용하여 주입
조립기 ( Assembler )
- 조립기가 객체 생성, 의존성 주입을 처리
- 예시 : 스프링 프레임워크
스프링은 위와 같이 설정을 통해 의존을 할 대상을 설정하고, 그것을 초기화하고 사용하게 된다.
DI의 장점
-
의존 대상이 바뀌면 조립기(설정)만 변경하면 된다.
위 코드에서도 볼 수 있듯이, OrderService가 의존하고 있는 Notifier가 바뀌더라도 조립기의 코드만 변경하면 된다.
-
의존하는 객체 없이 대역 객체를 사용하여 테스트가 가능해진다
테스트를 진행할 때, UserRepository를 의존하고 있을 때 실제 DB와 연결하는 Repository가 아닌 MemoryUserRepository를 설정을 통해 테스트를 진행 할 수 있음
DI를 습관처럼 사용하기
- 의존 객체는 주입받도록 코드를 작성하는 습관을 들이자.