brunch

매거진 SW개발

You can make anything
by writing

C.S.Lewis

by 김민석 Apr 05. 2016

DI

Dependency Injection

Spring의 3요소 중 하나가 DI/IoC인데 그 중에 DI부터 좀 살펴보려고 한다. 


DI를 해석하면 의존성 주입이다. 결국 두가지 개념.. 의존성과 주입을 알면 DI의 개념을 알 수 있다.

이 개념을 알기 전에 객체지향 개념의 전체적인 흐름부터 알고 갈 필요가 있다.


객체지향 프로그램의 실행의 전체적인 흐름은 다음과 같은 순서로 이루어진다.

1. 객체 생성

2. 객체간의 관계 형성

3. 객체간 대화


매우 일반화 했기 때문에 프로그램 중간에 서로 순서가 바뀔 수는 있지만 대략적으로 보면 저렇다. 특히, 1과 2는 프로그램의 초기화 과정이고 3번이 런타임 시간의 99.99%를 차지한다. 여기서 DI는 2번을 지칭한다. 따라서 DI를 잘 알면 객체지향 프로그램의 1/3은 알았다고 해도 과언이 아니다라고 그냥 생각하고 넘어가자..다른데서 이렇게 말하면 안된다.-0-;;; 암튼 그만큼 DI라는 개념은 겁나 중요하다.


그럼 DI를 알아보자.


첫째로 의존성부터 알아보자. 나는 너 없으면 못살아.가 의존이다. 이런 일반적으로 다 아는 얘기를 하는 이유는 객체지향 세계에서도 마찬가지이기 때문이다. A class가 B class에 의존이 있다면 A는 B를 항상 신경써야한다. 왜냐하면 B가 바뀌면 A한테도 영향이 있기 때문이다. 뭔가 바뀌면 나한테 영향이 있다. 이게 의존이다. 그래서 프로그램 유지보수 할 때 제일 짜증나게 하는 놈이다. 뭐하나 수정하려고 하면 그놈 한테 의존이 걸려있는 모든 얘들한테 영향이 가기 때문이다. 그래서 모든 객체지향 설계 기본.. 디자인 패턴.. 등등에서 항상 나오는 말이 의존은 인터페이스에 걸라고 한다. 왜냐하면 인터페이스는 태어날때부터 안바뀔 것으로 생각하고 만든 얘들이니까.. 그래서 만들 때 힘들어도 한번 만들어놓으면 마음이 편한 얘들.. 맘 놓고 의존 걸수 있는 애들..(물론 현실에서는 인터페이스도 바뀐다.. 그래서 더 짜증난다.. 자바에서 인터페이스에 새로운 기능을 추가하고 싶을 때는 여기를 보자.


아무튼 의존성은 이런 놈이다. 아키텍트가 하는 일의 본질이 설계 시 도메인 문제를 해결하면서 가장 의존성이 적은 설계를 찾는 것이라고 생각하면 된다. UML의 Class diagram의 화살표도 다 의존관계를 표현하고 있다. 의존 걸려있는 쪽으로 다 화살표가 향하고 있는데... 이게 다 너한테 신경쓰여서 계속 쳐다보고 있는 것이다!!! 라고 생각하면 기억하기 좋다..(상속 관계에서 왜 자식이 그토록 부모에게 그 커다란 화살표를 가리키고 있는지 이제 이해가 가는가? - 상속은 의존 관계 중 가장 강력크한 의존이다.)



이제 주입을 알아보자. 앞에 의존을 겁나 나쁘게 얘기했는데... 하지만 피할수는 없다. 객체 간 의존이 없이 만들려면 클래스 하나에 모든 걸 다 때려놓고 C처럼 짜야하는데 그건 절차지향적 프로그램일 뿐이다. 우리가 고민할 건 어떻게 의존을 최소화 할 것인가이다. 아래 소스를 보자.

학급이라는 클래스다. 필드변수로 학생 하나와 이름이 있다. 학생이 하나인게 현실적으로 좀 이상하지만 설명을 위해 대충 만들었으니 넘어간다. 여기서 의존관계는 Student와 맺고 있다. 따라서 학급은 항상 Student class가 바뀌는지 지켜보고 있어야 하는 입장이다. 물론 Student가 인터페이스라면 좀 더 상황이 나아지겠지만 말이다. 여기서 의존을 하는 방법은 두 가지다. 생성자에 student 객체를 주는 방법. setStudent()에 객체를 주는 방법. 물론 student가 private이 아니라면 직접 assign(=)해서 바로 넘길 수도 있다. 그러고 보니 총 3개다. 스프링 프레임워크에서 지원하는 주입 방법이 이렇게 세가지이다. 마지막 직접 어사인해서 하는 방법은 필드 변수에 @Autowired로 넣어줄 수 있는데 스프링이 참 편하긴하다. 이제 의존이 뭔지 알게 됐다.


그런데 왜  DI를 스프링에서 중요한 개념으로 생각하는 걸까? 그건 바로 의존 주입을 외부 설정에서 할 수 있게 해서 소스를 수정하지 않고도 의존 방법을 바꿀 수 있게 할 수 있기 때문이다. 아직 현업에서 굴러보지 않은 사람들은 이게 얼마나 좋은 건지 잘 모를 수도 있다. 프로그램은 소스에 의존하고 있다. 따라서 소스가 바뀌면 프로그램이 바뀐다. 프로그램이 바뀐다는건 배포를 다시 해야하고 배포를 다시 하기 위해서는 품질 검수를 다시 받아야 한다는 뜻이다. 한줄만 바껴도 말이다. 근데 소스를 안바꾸고 해결하는 방법이 존재한다면? 스프링은 이 DI를 굉장히 포괄적이고 광범위하게 지원하기 때문에 극단적인 예를 들자면 현장에서 오라클 DB를 쓰다가 Mysql로 바꿀때도 소스 한줄 바꾸지 않을 수 있다. 이거 아주 대단한 거라고!!!

매거진의 이전글 자바 인터페이스에 새로운 매소드를 추가하고 싶다면?
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari