IOC(제어의 역전)
IOC (Inversion of Control)는 제어의 역전을 의미합니다. 이는 소프트웨어 개발에서 프로그램의 제어 흐름이 개발자에게서 프레임워크나 컨테이너로 넘어가는 것을 말합니다.
스프링에서 생각을 해보자면.
상위모듈(구현체)이 하위모듈(인터페이스)에 의존하지 않도록, 클라이언트 코드에서의 수정이 이루어지지 않으면서 구현체를 갈아끼우도록
클레스파일을 따로 만들어서. 필요에 따라 구현체를 갈아끼우게 코드를 짜야합니다.
이로 인해 OCP, DIP 또한 만족 시킬 수 있습니다.
(물론 설정파일에서의 코드 수정은 일어나지만 이건 클라이언트 코드가 아니라 괜찮습니다...~~~)
클라이언트코드(로직파일, 내부파일), 설정코드(설정파일, 외부파일) 이라고 하였을떄
private final MemberRepository memberRepository;
memberRepository에는 어떤 구현체가 올지 아무도 모릅니다. 즉 클라이언트 코드에 대한 결정권을 외부파일이 가지고 있습니다.
즉 제어의 역전이 일어났다고 말 하는데 이러한 현상을 IOC라고 합니다.
DI
DI (Dependency Injection) 혹은 의존성 주입이라고 합니다.
의존성 주입은 클래스가 직접 자신이 필요로 하는 의존 객체를 생성하는 것이 아니라, 외부에서 의존 객체를 주입받는 방식입니다. 이를 통해 클래스 간의 결합도를 낮추고 유연한 구조를 갖출 수 있습니다.
private final Interface example = new Implementation();
예시로 이런식으로 객체를 생성을하게 되면. Interface example이라는 객체는 Implementation이라는 구현체를 가지게 되는데.
이건 사용자인 내가 필요에 따라 클라이언트 코드(외부가 아닌 내부)에서 객체를 선언을 하게 되는데.
private final Interface example;
//생성자 생략
위와 같은 방식으로 선언을 하고 구현체에 대한 선택권을 클라이언트코드(내부)가 아닌 설정파일(외부)에서 선언을 하고 설정파일에 따라 구현체를 주입받아 사용하는 방식을 의존성 주입 방식 이라고 합니다.
일반적으로 클래스 A가 클래스 B를 생성하여 사용하는 경우를 생각해보겠습니다. 이는 클래스 A가 클래스 B에 의존하고 있다는 것을 의미합니다. 그러나 IOC 컨테이너를 사용하여 클래스 A가 필요로 하는 클래스 B의 인스턴스를 외부에서 주입받게 되면, 클래스 A는 직접 클래스 B를 생성하지 않고 외부로부터 주입받아 사용하게 됩니다. 이것이 의존성 주입의 개념입니다.
IOC의 주요 장점
느슨한 결합(Loose Coupling): 클래스 간의 의존성이 줄어들어 변경에 민감하지 않은 코드를 작성할 수 있습니다.
테스트 용이성(Testability): 의존성을 주입하여 모의 객체(Mock Object)를 사용하여 테스트하기 쉽습니다.
재사용성(Reusability): 의존성 주입을 통해 재사용 가능한 코드를 작성할 수 있습니다.