
- 의존성이 무엇일까?
- 의존성을 어떻게 해결할까?
- 의존성 주입이 왜 필요할까?
지난 글을 통해 IoC 방식의 장점을 알아보았다. 이러한 스프링의 IoC 동작을 이해하려면 의존성과 의존성 주입의 개념 또한 알아야한다. 스프링은 DI, 의존성 주입이라는 핵심 기능을 통해 IoC 구조를 설계할 수 있게 해주고 있기 때문에 꼭 알아야하는 내용이다.
그래서 DI가 뭔데? 일단, 구글에 검색해보자.
DI란 Dependency Injection의 줄임말로 한글로 번역하면 의존성 주입이라는 말이다.
"의존성 주입"은 제어의 역행이 일어날 때 스프링이 내부에 있는 객체들간의 관계를 관리할 때 사용하는 기법이다.
의존성 주입은 말 그대로 의존적인 객체를 직접 생성하거나 제어하는 것이 아니라,
특정 객체에 필요한 객체를 외부에서 결정해서 연결시키는 것을 의미한다.
즉, 우리는 클래스의 기능을 추상적으로 묶어둔 인터페이스를 갖다 쓰면 되는 것이다.
나머지는 스프링에서 객체를 주입해주기 때문이다.
따라서 이러한 의존성 주입으로 인해 모듈 간의 결합도가 낮아지고 유연성이 높아진다.
의존성.. 객체들간의 관계.. 너무 어렵다..
의존성 그게 뭔데
다음과 같이 항공사에서 제공하는 고객 서비스가 있다.

여기서 비행기 티켓은 고객 서비스에 의존적인 관계이다. 왜냐하면, 고객이 티켓을 대한항공에서 예매할지, 아시아나에서 예매하는지에 따라 고객 서비스 자체를 바꿔줘야하기 때문이다. 예를 들어, 검표를 하는 상황을 가정해보자. 아시아나에서 만든 티켓에서는 검표를 checking()이라는 메서드로 정의하고 대한항공에서는 ticketing()이라는 메서드로 정의한다. 이 상황에서 대한항공 표를 아시아나 표로 바꾼다면, 고객 서비스 클래스 안에 존재하는 검표 메소드 호출을 전부 수정해야하는 상황이 발생하는 것이다. 즉 코드 관점에서 본다면 비행기 티켓 클래스가 바뀌면 고객 서비스 클래스의 서비스 로직 전체를 수정해야하는 것이다.
이렇게 한 클래스가 바뀔 때 다른 클래스가 영향을 받는다면 클래스 간에 의존 관계가 있다고 한다. 이렇게 클래스 간에 의존 관계가 있으면 클래스 하나를 변경하면 영향을 받는 코드 모두를 수정해줘야 하기 때문에 코드의 품질과 안정성이 떨어진다.
의존성을 해결하는 법

Java에서는 이러한 의존적인 객체의 관계를 인터페이스(interface)를 사용해 유연하게 처리할 수 있다. Ticket을 인터페이스로 만들고 이 인터페이스를 구현한 구현체 KalTicket Class과 AsianaTicket Class를 만든다. 이렇게 되면 고객 서비스 안에는 티켓이 대한항공인지 아시아나인지 상관없이 인터페이스의 메서드를 통해 원하는 메서드를 호출할 수 있다. 즉 티켓의 종류에 따라 코드가 변경될 일이 없어진다.
그럼 의존성 주입은 뭘까?
의존성 주입은 클래스 외부에서 객체를 생성한 뒤, 해당 객체를 클래스 내부에 주입하는 것이다.
의존성 주입이라는게 왜 필요한지 이해해보자. 여기 대한항공을 타고 수학여행을 가기로한 300여명의 학생이 있다. 이 학생의 고객 서비스 300여개의 클래스에는 이미 대한항공의 티켓 객체가 들어있을 것이다. 그런데, 이 학생들의 티켓을 아시아나로 변경하고자하면 어떻게 해야할까?
300여개의 클래스의 티켓 객체 선언부를 모두 찾아서 바꿔주어야한다. 즉, 클래스 하나를 변경하고자 할 때, 관리해야할 코드가 많아지는 것이다.

우리는 이를 해결하기 위해 의존성 주입을 사용한다. 외부에서 Ticket 인스턴스를 만들어 Ticket이 필요한 각 클래스에 주입한다.

이렇게 구조를 바꾼다면 서비스 클래스는 티켓 구현체를 주입받는 것 외에는 신경쓸 필요가 없어진다. 클래스를 변경하고 싶다면 컨테이너에서 선언한 인스턴스만 바꿔주면 되는 것이다.
스프링에서 이렇게 인스턴스를 저장하는 공간을 IOC Container라고 부른다. 객체의 대한 제어 권한은 모두 IOC Container에게 위임된다. IOC Container에서는 이러한 인스턴스들을 불필요하게 여러개 만들지 않고 단 하나만 생성하는 싱글톤 방식으로 관리하여 메모리 관리의 효율성을 제공한다.
Reference
'Develop' 카테고리의 다른 글
| [디자인 패턴] 싱글톤 디자인 패턴(Singleton Design Pattern) (0) | 2022.04.28 |
|---|---|
| [Spring] properties 파일을 이용한 DI (0) | 2022.04.27 |
| [Spring] @Autowired, @Resource, @Inject의 차이 (0) | 2022.04.26 |
| [Spring] XML을 이용한 DI (0) | 2022.04.26 |
| [Spring] IoC 제어 방식 (Inversion of Control) (0) | 2022.04.25 |