의존성 주입이란?
A 객체가 어떤 작업을 수행하기 위해서 B 객체를 필요로 하는 경우 두 객체 사이에 의존성이 존재한다고 표현한다. 이때 A 객체가 아닌 외부에서 B 객체를 생성한 뒤 이를 전달해 의존성을 해결하는 방법을 의존성 주입(Dependency Injection) 이라고 한다.
유연하고 재사용할 수 있는 설계를 만들기 위해서는 코드의 변경 없이 다양한 실행 구조를 만들 수 있어야 하고, 의존성 주입은 이를 돕는다.
예를 들어, A 객체 내부에서 B 객체를 직접 생성하는 경우에는 B 객체에 대한 결합도가 높아진다.. 반면, B 객체에 대한 생성 책임을 외부로 위임하고 외부에서 A 객체에게 B 객체를 전달해주는 방식(의존성 주입) 을 통해서는 A 객체가 B 객체에 대한 결합도를 낮추는 유연한 설계를 만들 수 있다.
의존성 주입의 장점은 다음과 같다.
- 런타임에 의존성을 유연하게 변경이 가능하다.
- Mock or Stub 객체를 활용한 유연한 테스트가 가능하다.
- 우리가 흔하게 유지보수하기 좋은 객체지향적인 프로그램은 응집도가 높고, 결합도가 낮아야 한다고 표현한다.
의존성 주입의 3가지 핵심 방식과 선택 가이드
생성자 주입
가장 흔하게 사용되고 권장되는 방식. 객체를 생성할 때 필요한 모든 의존성을 생성자의 인자로 받아 초기화한다.
장점
- 필수 의존성 강제(Java final 키워드 사용 케이스) : 객체 생성 시점에 모든 필수 의존성이 주입됨을 보장한다.
- 불변성 보장 : 한 번 주입된 의존성은 변경되지 않으므로 객체의 안정성이 높다.
- 테스트 용이성 : 필요한 의존성이 명확하여 Mock 객체 주입이 가장 자연스럽다.
언제 사용할까?
가장 보편적으로 사용한다. 특히 객체가 제대로 작동하기 위해 필요한 필수적인 의존성이 있는 때 최적이다.
그리고 생각보다. 한 번 주입된 의존성이 변경되는 경우를 찾기 힘들다.. 때문에, 최적의 선택지!
Setter 주입
클래스 내부에서 정의된 Setter 메서드를 통해 의존성을 주입하는 방식. 객체가 생성된 후에 필요한 의존성을 설정할 수 있다.
장점
- 선택적 의존성 주입 : 항상 필요한 것은 아니거나 나중에 변경될 수 있는 의존성에 유연하다.
- 하지만, 여러명이 같이 개발하는 프로젝트에서 Setter 를 만들어 놓으면, 항상 의도하지 않은 방향으로 사용해 장애가 발생할 수 있다..
- 정말 필요한 경우가 아니라면 사용하지 않는것이 좋다.
- 객체 생성 유연성 : 의존성 없이도 객체 자체는 생성될 수 있다.
언제 사용할까?
객체가 생성된 후에도 변경될 수 있는 선택적 의존성이 있거나, 레거시 코드에 DI 를 적용할 때 기존 생성자를 수정하기 어려울 때 고려해볼 수 있다. 하지만 필수 의존성에는 사용하지 않는것이 좋다.
필드 주입
클래스 필드에 직접 의존성을 주입하는 방식으로, 주로 Spring 프레임워크에서 @Autowired 같은 애노테이션과 함께 사용된다.
단점
- 프레임워크와 강한 결합 : 특정 DI 프레임워크에 강하게 의존되어서 프레임워크 없이는 테스트나 객체 생성이 어렵다.
- 테스트 용이성 저하 : private 필드에 Mock 객체를 주입하기 어렵다.
언제 사용할까?
사용하지 말아라.. 테스트 용이성 저하, 프레임워크와 강한 결합은 DI 의 목적(객체지향, 유지보수성 향상, 테스트 용이성) 과 맞지 않는 방법이다.
'Backend > 소소한 백엔드 개발 이야기' 카테고리의 다른 글
| HTTPS 통신 방식 (0) | 2025.06.08 |
|---|---|
| JWT(JSON Web Token) (0) | 2025.06.03 |