직장에 차를 몰고 가는 것은 내가 차를 제어하는 것이다.
직접 차를 운전하는 대신 운전 기사를 고용한다면 이것을 제어의 역전이라고 한다. 차를 직접 운전할 필요가 없고 운전자가 운전하게 함으로써 본업에 집중할 수 있다.
소프트웨어 공학의 주요 원칙 중 하나는 클래스 간의 상호 의존성을 최소로 가져야 한다는 것이다. (low coupling; 낮은 수준의 결합)
IOC는 클래스 간의 결합을 느슨하게 해 테스트와 유지 관리를 더 쉽게 하는 설계(design) 원칙이다. IOC란 메인 프로그램에서 컨테이너나 프레임워크로 객체와 객체의 의존성에 대한 제어(control)를 옮기는 것을 말한다.
IOC는 설계(디자인) 패턴이 아니라 원칙이다. 세부 구현 사항은 개발자에게 달려 있다. IOC는 높은 레벨의 가이드라인을 제공하는 것 뿐이다.
IOC와 DI(의존성 주입; Dependency Injection)가 종종 같은 의미로 사용되지만, 의존성 주입은 IOC가 구현된 한 가지 예일 뿐이다.
Inversion of Control allows a framework to
제어의 역전이 구현된 예는 다음 세 가지가 있다.
3번에 대해서 - 예를 들어 자바에서 Main()이 프로그램의 흐름을 제어한다고 하자. GUI기반 앱을 만들어 이 프로그램에 IOC를 적용할 수 있다. 사용자가 입력할 수 있도록 하는 입력폼 창을 만들어 띄우면, 프레임워크가 이벤트를 사용해 프로그램의 흐름을 제어하게 된다.
A 객체가 B 객체의 메서드를 필요로 할 때를 생각해 보자. A클래스 안에 B클래스의 생성자를 사용해 B의 인스턴스를 만들어 사용하는 대신, 의존성 주입은 다음 세 가지 방법 중 하나를 써서 B클래스가 A클래스에 주입되도록 한다.
서비스 로케이터 패턴에는 애플리케이션이 제공하는 모든 서비스에 대한 정보를 담고 있는 서비스 로케이터 객체가 있다. 인스턴스를 생성할 때 서비스는 서비스 로케이터에 자신을 등록한다. 클라이언트로부터 요청을 받으면 서비스 로케이터가 필요한 작업을 수행하고 필요한 값을 반환한다. 이 패턴 역시 의존 클래스 간의 결합을 느슨하게 한다.
스프링 프레임워크는 IOC구현의 좋은 예다. 스프링 컨테이너는 프로그램 내 객체의 라이프사이클(수명 주기)을 인스턴스로 만들어 관리한다. 사용자는 configuration 파일(구성, (환경)설정 파일)에서 애플리케이션에 필요한 객체 및 의존성에 대한 정보를 제공한다. 이 파일은
자바 빈(bean)과 그 configuration xml 설정에 대한 간단한 예를 살펴보자.
빈이 뭐지?! 참고 https://velog.io/@virtualplastic/Spring-Bean-%EB%B9%88
package edpresso.ioc;
public class Student {
private String name;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
<bean id="student" class="edpresso.ioc.Student">
<constructor-arg index="0" value="Paul"></constructor-arg>
</bean>
XML파일 안에 이 빈이 있다는 것은, 애플리케이션이 구동되면 스프링 컨테이너가 이 빈을 인스턴스로 생성한다는 것을 의미한다. XML파일의 빈 정의에는 빈의 의존성 정보도 포함되어 있다.
예를 들어 Course라는 이름의 클래스가 Teacher 객체에 의존하고 있다고 하자. 우리는 XML 설정 파일에다가 Course 빈의 정의와 Teacher 빈에 대한 의존성을 적을 것이다. 그러면 객체 생성의 책임은 스프링이 지게 된다. 스프링이 Course 빈을 만나서 Teacher 빈에 대한 의존성이 있다는 것을 알게 되면, 자동으로 Teacher 빈의 인스턴스를 먼저 생성하고 Course 빈에 이를 주입한다.