의존성 주입
- 정의 : 객체 간의 의존 관계를 외부에서 주입하는 설계 패턴
- 원칙
- 상위 모듈은 하위 모듈에서 어떠한 것도 가져오지 않아야 한다.
- 두 모듈은 모두 추상화에 의존해야 한다
- 추상화는 세부사항에 의존하지 않아야 한다.
장점
- 모듈화와 재사용성
- 객체 간의 결합도를 낮추어 모듈화가 쉬워지고, 코드의 재사용성을 높일 수 있다
- 테스트 용이성
- 의존성을 외부에서 주입받기 때문에, 테스트시 Mock 객체를 쉽게 주입할 수 있다.
- 유지보수성
- 객체 간의 직접적인 결합이 줄어들어, 변경 사항이 다른 객체에 미치는 영향을 최소화 할 수 있다.
- 코드 가독성
- 의존성을 명시적으로 주입하므로 코드의 의도를 파악하기 쉽다
- 확장성
- 객체를 쉽게 교체하거나 확장할 수 있기 때문에, 유연한 시스템 설계가 가능하다.
단점
- 초기 설정 복잡성
- Spring과 같은 DI 컨테이너를 사용하는 경우, 설정이 복잡해질 수 있다
- 러닝 커브
- DI 패턴과 DI FrameWork를 이해하고 사용하는데 시간이 필요하다
- 추적의 어려움
- 의존성이 외부에서 주입되기 때문에, 객체의 생성 경로나 흐름을 추적하기 어려울 수 있다
- 과도한 의존
- 잘못된 설계로 DI 컨테이너에 지나치게 의존하면, 코드가 DI 프레임워크에 종속될 위험이 있다.
사용하는 곳
- 대규모 앱
- 모듈화 및 유지보수가 중요하기 떄문에 사용한다
- 테스트 주도 개발 (Test Driven Development)
- 의존성 주입을 목해 목업 객체를 사용하여 Unit Test를 쉽게 작성할 수 있다.
- 프레임워크 기반 개발
- Spring, Guice 등 DI 프레임워크를 사용하는 환경에서 많이 활용된다
- 다양한 구현체를 사용하는 경우
- 인터페이스 기반 설계로 구현체를 유연하게 교체해야 하는 상황에서 유용하다!
예제 코드 (Java, Spring 기준)
- 인터페이스 정의
public interface MessageService {
void sendMessage(String message);
}
- 구현체
public class EmailService implements MessageService {
@Override
public void sendMessage(String message) {
System.out.println("보낸 이메일: " + message);
}
}
- 의존성 주입
@Component
public class NotificationService {
private final MessageService messageService;
@Autowired
public NotificationService(MessageService messageService) {
this.messageService = messageService;
}
public void notify(Stribng message) {
messageService.sendMessage(message);
}
}
- Spring 설정 실행 (기본 값 가져와도 됩니다.)
@SpringBootApplication
public class DiExampleApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(DiExampleApplication.class, args);
NotificationService notificationService = context.getBean(NotificationService.class);
notificationService.notify("Hello, DI");
}
}
'CS > 기타' 카테고리의 다른 글
(CS) 네트워크 - 네트워크 계층 IP (0) | 2025.03.22 |
---|---|
(CS) 네트워크 - 물리 계층과 데이터 링크 계층 (0) | 2025.03.19 |
(CS) 네트워크 - 기본구조 (1) | 2025.03.18 |
(CS) 정렬 - 퀵 정렬 (0) | 2025.01.21 |
(CS) SOLID 원칙 (0) | 2025.01.07 |