프로그램의 제어 흐름을 내가 직접 쥐지 않고 밖에서 관리하게 하는 것. 객체를 언제 만들지, 어떤 메서드를 부를지를 프레임워크 같은 외부가 정한다.

부품을 스스로 정하는 객체

객체가 자기 부품을 스스로 정하면 바꾸려 할 때마다 그 객체를 고쳐야 한다. 떡볶이를 만드는 클래스가 생성자 안에서 new RiceTTok()으로 쌀떡을 만들어 쓰고 있다면, 밀떡으로 바꾸는 데 클래스 자체를 손대야 한다.

재료를 밖에서 받게 바꾸면 쌀떡이든 밀떡이든 무엇이 들어와도 그 클래스는 그대로다. 역할과 관심이 분리되어 객체 사이의 응집도가 올라가고 결합도가 내려간다. DIPOCP가 IoC 없이 성립하지 않는 것도 그래서다.

원칙과 그 구현체

IoC는 원칙 그 자체다. 이것을 실제로 해줄 구현체가 따로 있어야 하고, 그 대표가 의존성 주입이다. 치즈떡볶이가 스스로 재료를 결정하지 못한다는 추상적인 개념이 IoC라면, 그 재료를 외부에서 정해준다는 구체적인 행위가 DI다. 면접에서 둘의 관계를 묻는 것이 이 구분 때문이다. 직접 만드는 코드와 밖에서 받는 코드를 나란히 놓고 본 것은 의존성 주입에 있다.

스프링에서는 컨테이너가 그 자리를 맡는다. 자바 객체의 생명 주기를 컨테이너가 관리하면서 필요한 의존성까지 넣어주므로, IoC와 DI가 함께 적용되는 지점이 스프링 컨테이너다.

제어의 방향과 의존의 방향

IoC와 DIP는 둘 다 원칙이고 목적도 같다. 클래스 간 결합을 느슨하게 해서 변경의 파급을 줄이려는 것이다. 뒤집는 대상이 다를 뿐으로, IoC는 제어의 방향을 뒤집고 DIP는 의존의 방향을 뒤집는다.

프레임워크와 라이브러리

프레임워크와 라이브러리를 가르는 기준도 같은 이야기다. 내가 능동적으로 불러 쓰면 라이브러리이고, 내 코드가 수동적으로 불려 나가면 프레임워크다. 흐름을 쥔 쪽이 어디냐가 기준이고 그것이 곧 IoC다. 자세한 것은 프레임워크와 라이브러리에 있다.

관련

출처