의존성 주입 가이드: DI는 왜 테스트와 변경에 도움이 될까
Dev

의존성 주입 가이드: DI는 왜 테스트와 변경에 도움이 될까


객체 지향과 SOLID를 공부하다 보면 dependency injection, 즉 DI라는 개념도 자주 같이 나옵니다. 처음에는 프레임워크 설정이나 복잡한 패턴처럼 느껴질 수 있지만, 핵심은 의외로 단순합니다. “필요한 객체를 직접 만들지 말고, 바깥에서 주입받자”는 것입니다.

이 글에서는 아래 내용을 정리합니다.

  • dependency injection이 무엇인지
  • 왜 강한 결합을 줄이는 데 도움이 되는지
  • 왜 테스트와 변경에 유리한지
  • SOLID와는 어떤 관계가 있는지

핵심은 DI는 객체 생성 방식의 문제가 아니라, 코드가 구체 구현에 덜 묶이도록 만드는 의존성 설계 방식이라는 점입니다.

dependency injection이란 무엇인가

어떤 객체가 필요한 의존성을 자기 안에서 직접 생성하지 않고, 외부에서 받아 쓰는 방식을 말합니다.

예를 들어 서비스 객체가 내부에서 바로:

  • 데이터베이스 객체 생성
  • 메일 발송 객체 생성

을 해버리면 구현에 강하게 묶입니다.

반대로 필요한 객체를 생성자나 메서드로 주입받으면 더 유연해집니다.

왜 결합도를 줄일까

직접 생성하면 그 구현에 강하게 묶입니다. 그러면:

  • 다른 구현으로 바꾸기 어렵고
  • 테스트용 대체 객체를 넣기 어렵고
  • 변경 영향이 커집니다

DI는 이 결합을 약하게 만들어줍니다.

즉, “무엇을 쓸 것인가”와 “어떻게 동작할 것인가”를 조금 더 분리하는 효과가 있습니다.

왜 테스트에 유리할까

테스트에서는 진짜 DB나 외부 API 대신:

  • mock
  • fake
  • stub

같은 대체 객체를 넣고 싶은 경우가 많습니다.

DI를 쓰면 이런 대체 구현을 넣기 쉬워집니다. 반대로 내부에서 직접 객체를 생성하면 테스트가 훨씬 불편해질 수 있습니다.

SOLID와는 어떤 관계가 있을까

DI는 특히 DIP와 자주 연결됩니다.

즉:

  • 구체 구현보다 추상에 의존하고
  • 실제 구현은 바깥에서 연결하는 방식이

DI와 잘 맞습니다.

그래서 DI는 객체 지향 설계와 SOLID를 실제 코드로 옮길 때 자주 쓰이는 도구입니다.

자주 하는 오해

1. DI는 프레임워크 기능이다

프레임워크가 도와줄 수는 있지만, 본질은 설계 방식입니다.

2. DI를 쓰면 무조건 코드가 좋아진다

작은 코드에 과하게 적용하면 오히려 복잡해질 수 있습니다.

3. 인터페이스를 많이 만들면 곧 DI다

중요한 것은 개수가 아니라, 실제로 결합을 느슨하게 만들었는가입니다.

FAQ

Q. 입문자는 DI를 어디서부터 써보면 좋을까

DB 접근, 외부 API 호출, 알림 발송 같은 외부 의존성부터 분리해보는 것이 좋습니다.

Q. 생성자 주입이 많이 언급되는 이유는 무엇인가

필요한 의존성을 명확하게 드러내기 쉽기 때문입니다.

Q. 모든 객체에 DI를 적용해야 하나

그럴 필요는 없습니다. 변화 가능성이 크고 대체 구현이 필요한 부분부터 적용하는 편이 실용적입니다.

먼저 읽어볼 가이드

검색 유입이 많은 핵심 글부터 이어서 보세요.