Inversion of Control , Dependency Injection

2021. 3. 15. 19:12개발/기타

 

 헷갈리는 IoC와 DI에 대한 개념을 정리합니다.

 

 

Wiki에서 알려주는 Inversion of Control의 역사


Inversion of Control이라는 용어는 Michael Mattsson의 논문에서 처음으로 언급되었으며, Stefano Mazzocchi가1999년에 아파치 소프트웨어 재단 프로젝트에서 인용하면서 유명세를 탓다. 그 후 2004년 Robert C. Martin과 Martin Fowler에 의해 더욱 대중에게 알려지게 된다. 

 

 

Inversion of Control


마틴 파울러가 작성한 Inversion of Control을 읽다가 너무 안읽혀서 그냥 Stack Overflow에서 정답에 가까운 답변을 종합해서 작성했다. 

 

Inversion of Control은 상당히 범용적으로 쓰이는 용어중 하나다. 특정 코드를 구현하는 디자인 패턴이 아니라 코드를 작성하기 위한 "원칙"이라고 말하는게 맞다. 

 

Inversion of Control의 원칙을 지키지 않는 경우를 보자. 아주 흔히 작성하는 코드다. 

print "enter your name"
read name
print "enter your address"
read address
etc...
store in database

"enter your name"을 출력(print)하고 사용자가 입력한 정보를 name변수가 받는다(read). 이런식으로 정해진 순서에 따라 사용자는 정보를 입력하고 마지막에 데이터 베이스에 저장한다. 

 

반대로 Inversion of Control의 원칙을 지킨 경우를 보자. 흔히 우리가 사용하는 GUI ( 또는 Windowing System )을 예로 들수 있겠다. 

when the user types in field a, store it in NAME
when the user types in field b, store it in ADDRESS
when the user clicks the save button, call StoreInDatabase

사용자가 field a에 타이핑을 했을때 name에 데이터를 저장한다. 여기서 핵심은 when the user types다. 

화면에 수많은 기능들이 있겠지만 해당 기능을 언제 실행할지는 사용자가 결정한다. 

 

첫번째 작성한 코드는 반드시 name을 입력하고, address를 입력하도록 개발자가 코드를 작성했다. 하지만 두번째 코드를 보면 개발자는 name과 address를 입력받을 수 있도록 구현은 해뒀지만 언제 해당 기능이 사용될지는 사용자에게 달려있다. 

이 경우 name과 address의 입력과 저장에 대한 제어권이 개발자에서 사용자로 넘어갔다. ( Inversion of Control )

 

 

 

Dependency Injection 


의존성 주입은 객체의 의존성을 다른 객체 또는 프레임워크( 의존성 주입자 )가 전달하는 것을 의미한다. 

 

의존성은 아래 예시를 보면 이해가 쉽게 된다.

A클래스를 수정했을때 B 클래스도 함께 수정해야 할 경우, "B가 A에 의존하고 있다"고 한다. 

 

의존성을 주입받지 않는 예제를 하나보자. SomeClass의 생성자를 보면 Other11 클래스를 인스턴스화 하고 있다. 

만약 Other11 클래스의 이름을 Other22로 바꾼다면 아래 코드도 함께 변경해야한다. 

따라서 SomeClass는 Other11 클래스에 의존하고 있다. 

public SomeClass() {
	
    private Other other; // 인터페이스
    
    public SomeClass(){
    	this.other = new Other11();
    }
    
}

 

아래 코드는 SomeClass가 의존성을 주입받는 경우다. 이전에 SomeClass의 생성자에서  new를 통해 직접 인스턴스화 했지만, 현재는 외부에서 이미 생성된 인스턴스를 주입 받는다. 

 

public SomeClass() {
	
    private Other other; // 인터페이스
    
    public SomeClass(Other other){
    	this.other = other;
    }
    
}

 

위 예시에서 첫번째 코드는 내가 직접 명시적으로 Other11을 인스턴스화 하겠다고 작성했다. 따라서 SomeClass를 인스턴스화 할때 무조건 Other11도 함께 인스턴스가 생성된다. 

 

하지만 두번째 코드의 SomeClass 생성자를 보면 파라미터를 통해 인스턴스를 주입받는다. 따라서 인스턴스화에 대한 제어권이 사라졌다. 어디서 SomeClass를 사용할진 모르겠지만 SomeClass 클래스는 이제 생성자를 통해 주입된 인스턴스를 사용해야한다. 

 

첫번째 코드의 의존성을 제거하기 위해 DI를 활용했으며, 그 결과 Inversion of Control이 발생했다. 

 

Dependency Injection은 Inversion of Control 원칙을 지킬 수 있도록 하는 하나의 프로그래밍 테크닉이다.

 

 

참고사이트


 

bliki: InversionOfControl

a bliki entry for InversionOfControl

martinfowler.com

 

 

What is Inversion of Control?

Inversion of Control (IoC) can be quite confusing when it is first encountered. What is it? Which problem does it solve? When is it appropriate to use and when not?

stackoverflow.com

 

 

의존성 주입

위키백과, 우리 모두의 백과사전. 소프트웨어 엔지니어링에서 의존성 주입(dependency injection)은 하나의 객체가 다른 객체의 의존성을 제공하는 테크닉이다. "의존성"은 예를 들어 서비스로 사용할

ko.wikipedia.org

 

 

What is dependency injection?

There have been several questions already posted with specific questions about dependency injection, such as when to use it and what frameworks are there for it. However, What is dependency inject...

stackoverflow.com