Spring의 다형성을 이용해 SOLID 객체지향에 손쉽게 맞춰주게 도와주는 Spring 프레임워크 기능인
IOC, DI
에 대해 알아보자.
IOC(Inversion of Control)
기존에는 new를 통해 클라이언트(개발자)가 스스로 어떤 구현체를 사용할 지 결정하였다.
- 문제점
개발자가 직접 구현체를 고르고 인스턴스로 선언하고 사용하게 되면, SOLID 원칙의DIP 의존관계 역전 원칙 (Dependency inversion principle)
,
한 클래스는 추상체인 interface만 바라보고 개발을 할 수 있어야 한다. (구현체를 갈아끼워야 하므로)
OCP 개방-폐쇄 원칙 (Open Close principle)
,
구현체를 new 하여 사용하게 되면, Runtime시에 구현체가 결정되는 Spring의 동작에 반해
매번 소스코드에 선언된 new 구현체를 소스 수정하여 변화에 폐쇄적이라는 원칙을 어기고,
interface가 없다면, 구현 또한 편하게 찍어내듯 개발하지 못하여 구현에도 개방적이지 못하다.
SRP 단일 책임 원칙 (Single Responsibility principle)
을 위반한다.
한 클래스는 하나의 책임만을 가지고 있어야 한다. 여기서 책임이란 클래스는 자신이 담당한 기능 구현에만 집중하도록, 한 기능의 모든 것을 담당하도록 한다는 것이다. 추후 해당 기능을 수정할 때 한 클래스만 수정하여 사이드 이펙트가 적게하고 어떤 구현체를 사용할지는 설정에 맡긴다.
- 이런 문제점들을 해결하기 위해, Spring이 개발자 대신 어떤 구현체를 삽입할지 Runtime시에 가변적으로 수행해주고 Spring의 LifeCycle에 맞춰서 규칙적으로 동작하게 해준다.
- 이 제어의 역전으로 AOP, public 메서드 수행순간에 특정 작업 하기, Constructor 생성 전에 어떤 작업 부탁 등이 가능해진다.
이렇게 제어를 역전하여 특정 LifeCycle에 맞춰서 개발을 하면 되는 경우에 특정 프레임 워크
를 사용한다고 하는데,
라이브러리와 잘 구분하여야 한다.
프레임워크 vs 라이브러리
프레임워크
는 LifeCycle에 맞춰 대신 실행해준다. (JUnit같이)라이브러리
는 내가 직접 new 하여 인스턴스를 생성하는 등, 직접 제어의 흐름을 통제한다.
의존관계 주입, 의존성 주입 DI(Dependency Injection)
실제 구현체(Impl)들은 인터페이스에만 의존하여 어떤 구현체가 사용되고 있는지 모른다.
그저 interface에 있는 메서드들로 내 비즈니스로직을 구현한다.
- Runtime시에 특정 Class에 주입되는 구현체를 결정한다. (사전에는 어떤게 들어갈지 해당 class만 보고서는 몰라야 한다.)
- Runtime시에 외부에서 실제 구현 객체를 생성하고, 클라이언트에 전달해서 클라이언트와 서버의 실제 의존관계가 연결 되는 것이다.(의존 관계 주입)
- 매번 구현체가 변할 때 마다 교체되는 관계를
동적인 객체 인스턴스 의존 관계
라고 한다. - 반면, Interface와 의존 관계가 있어서 변하지 않는 관계를
정적인 객체 의존 관계
라고 한다.
IOC컨테이너 == DI 컨테이너
객체를 생성하고 관리하면서 의존관계를 연결해주는 것들이다.
어떤 추상체에 Impl을 만들어 주입해주고, 흐름을 제어해주는 것들을 칭한다.