의존성 주입 (DI)과 제어 역전 (IOC)의 차이점


117

DI (Dependency Injection) 및 IOC (Inversion Of Control)에 대한 많은 참조를 보았지만 차이점이 있는지는 잘 모르겠습니다.

둘 중 하나 또는 둘 다 사용하기를 원하지만 어떻게 다른지 조금 혼란 스럽습니다.


컨트롤 반전은 일반적으로 "컨테이너"를 참조하고 의존성 주입은 실제 패턴을 나타냅니다. 그러나 그들은 손을 잡고 간다. Martin Fowler의 기사 를 읽고 주제를 다루는 것이 좋습니다 .
벤 호프 슈타인

의존성 주입은 사용자가 수행하는 작업으로, Inversion of Control이라는 명령 구조로 이어집니다. 그들은 본질적으로 연결되어 있습니다.

2
DI는 IoC의 한 형태입니다. 저는 이 답변

2
DI는 IOC의 특별한 경우라고 말하고 싶습니다. 기존의 제어는 모듈 관리자에서 모듈 요청 모듈로 이동합니다. DI에서는 모듈 관리자로 전환되어 모듈에서 요청 된 종속성을 얻습니다.
Rafał Dowgird

즉, 기본적으로 IoC는 DI를 사용하는 구현입니다. 내가 올바르게 받고 있습니까?
dance2die

답변:


53

정의

Inversion of control은 응용 프로그램 프레임 워크 코드에서 구체적인 구현에 대한 인식을 줄이고 응용 프로그램의 도메인 별 구성 요소에 대한 제어를 강화하는 것을 목표로하는 디자인 패러다임입니다. 기존의 하향식 설계 시스템에서는 응용 프로그램의 논리적 흐름과 종속성 인식이 맨 처음 구성 요소에서 마지막으로 설계된 구성 요소로 흐릅니다. 따라서 제어 역전은 응용 프로그램에서 제어 및 종속성 인식의 거의 문자 그대로의 반전입니다.

의존성 주입은 컴파일 타임에 해당 기능을 제공하는 데 어떤 구현이 사용 될지 모르면서 다른 클래스가 의존하는 클래스의 인스턴스를 만드는 데 사용되는 패턴입니다.

같이 일하다

특정 기능을 제공하는 구성 요소를 작성하기위한 메커니즘이 필요하기 때문에 제어 반전은 종속성 주입을 사용할 수 있습니다. 액티베이터, 팩토리 메소드 등과 같은 다른 옵션이 존재하지만 사용되지만 프레임 워크 클래스가 대신 필요한 종속성 (들)을 받아 들일 수있는 경우 프레임 워크는 해당 유틸리티 클래스를 참조 할 필요가 없습니다.

이러한 개념의 실제 예는 Reflector 의 플러그인 프레임 워크입니다 . 응용 프로그램이 컴파일 타임에 플러그인에 대해 아무것도 몰랐더라도 플러그인은 시스템을 많이 제어합니다. 각 플러그인마다 단일 메소드가 호출됩니다. 메모리가 제공되면 초기화하여 제어를 플러그인으로 전달합니다. 프레임 워크는 그들이 무엇을할지 모르는 것뿐입니다. 주 응용 프로그램에서 제어를 수행하여 특정 작업을 수행하는 구성 요소를 제어했습니다. 제어 역전.

응용 프로그램 프레임 워크를 사용하면 다양한 서비스 공급자를 통해 해당 기능에 액세스 할 수 있습니다. 플러그인은 작성 될 때 서비스 제공자에 대한 참조를 제공합니다. 이러한 종속성을 통해 플러그인은 자체 메뉴 항목 추가, 파일 표시 방법 변경, 해당 패널에 자체 정보 표시 등을 수행 할 수 있습니다. 인터페이스가 종속성을 전달하므로 구현이 변경 될 수 있으며 변경 사항이 중단되지 않습니다. 계약이 그대로 유지되는 한 코드.

당시 팩토리 메소드는 구성 정보, 리플렉션 및 Activator 객체 (최소한 .NET)를 사용하여 플러그인을 작성하는 데 사용되었습니다. 오늘날, MEF 는 하나의 툴로, 애플리케이션 프레임 워크가 플러그인 목록을 종속성으로 수용하는 기능을 포함하여 종속성을 주입 할 때 더 넓은 범위의 옵션을 허용합니다.

요약

이러한 개념을 독립적으로 사용하고 이점을 제공 할 수 있지만 함께 사용하면 훨씬 유연하고 재사용 가능하며 테스트 가능한 코드를 작성할 수 있습니다. 따라서 이들은 객체 지향 솔루션을 설계 할 때 중요한 개념입니다.


3
아니요, IoC는 오래된 개념이며 DI (IoC에 의존하지 않음)와 독립적입니다. 예를 들어 Struts 프레임 워크 (Java)를 사용하면 IoC에 많이 의존하지만 DI는 사용하지 않습니다.
Rogério 2016 년

1
@ Rogério-당신은 두 개념이 서로를 요구하지 않는다는 좋은 지적을합니다. 나는 그것을 명확히하기 위해 대답을 업데이트 한 다음 일부 프레임 워크가 프레임 워크를 함께 사용하여 더 느슨하게 결합 된 코드를 허용하는 방법을 신속하게 설명합니다.

IoC의 가장 간단한 응용 프로그램은 아마도 ActionListener 일 것입니다. 코드를 절차 적으로 처리하는 대신 이벤트 처리 코드가 사용자 지정 코드로 위임됩니다. 이에 의해 제어를 반전시킨다.
mike

0

IOC와 DI를 이해하는 좋은 기사 http://martinfowler.com/articles/injection.html

IOC (제어 역전)

IOC는 의미

  1. 인터페이스 코딩 (하나의 구성 요소는 다른 구성 요소의 인터페이스에 의존해야하며 impl이 아닌)

    interface iComp_2 {...}
    
    class Comp_1 {
        iComp_2 c2 = ….;
    }
    
  2. 컴포넌트 구현 특정 코드 제거

    Comp_1 {
        iComp_2 c2 = getComp_2_Impl(); // not new Comp_2_Impl();
    }
    

IOC는 다음 중 하나에 의해 달성 될 수 있습니다.

1. DI (종속성 주입)

3 types of DI

1.1 Constructor Injection

1.2 Setter Injection

1.3 Interface Injection

2. 서비스 로케이터

DI (종속 주입) 컨테이너

런타임 impl 결정 및 컴파일 시간 아님 : 런타임에 일부 구성 파일을 기반으로 사용할 인터페이스의 구체적인 구현을 결정합니다 (따라서 컴파일 타임에 어떤 impl이 사용 될지 알지 못하므로 응용 프로그램의 구성 가능성이 증가 함) . 서로 다른 모듈 간의 구체적인 관계가 "런타임"에 결정되는 구현입니다.

의존성 주입 후 impl의 인스턴스화 : impl을 결정한 후 먼저 모든 종속성 (구성 파일에 지정됨)을 작성한 다음 해당 종속성을 해당 impl에 주입하여 impl을 인스턴스화합니다.

인스턴스 수명주기 관리 : DI 컨테이너는 일반적으로 수명주기를 관리하는 데 필요한 객체 또는 싱글 톤 또는 플라이 웨이트와 같은 향후 주입에 재사용되는 객체 만 참조합니다. 컨테이너를 호출 할 때마다 일부 구성 요소의 새 인스턴스를 작성하도록 구성된 경우 컨테이너는 일반적으로 작성된 오브젝트를 잊어 버립니다. 그렇지 않으면 가비지 수집기는 더 이상 사용하지 않을 때 이러한 모든 개체를 수집하는 데 어려움을 겪게됩니다.


6
"주사"기사를 정말로 읽었습니까? IOC는 이 답변이 말하는 것이 아니라 전혀 의미 하지 않습니다 .
Rogério 2016 년

-3

"Inversion of Control"은 모든 모듈이 추상 엔티티로 생각되는 시스템을 설계하는 방법이라고 말합니다.

그리고 "종속성 주입"은 서로 다른 모듈 간의 구체적인 관계가 "런타임"에 결정되는 구현입니다.


-4

제어의 반전은 일반적인 개념이며, 기능적 언어에서는 일반적으로 연속을 사용하여 수행됩니다. 이를 통해 양쪽이 '호출자'이고 '칼리'가없는 API를 작성할 수 있습니다. 다른 정적 환경에서는 이러한 기능이 없으므로 제어 흐름에 힌트를 삽입하려면이 핵이 필요합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.