제어 역전이란 무엇이며 언제 사용해야합니까?


답변:


62

IoC ( Wikipedia의 Inversion of Control 참조 )는 필요한 정보 나 기능이 없기 때문에 구성 요소가 작업을 완전히 수행 할 수없는 경우에 적용 할 수 있습니다.

IoC 패턴 의 가장 간단한 예는 C의 콜백 함수입니다. 예를 들어 함수를 선언 할 수 있습니다.

void Iterator(void *list, Func* f)

각 항목에 함수를 list적용하는 것을 반복 f합니다. 이 Iterator함수는 각 항목의 처리 방법을 모르고 함수를 인수로 제공하기 만하면 처리합니다.

앞의 예에서 볼 수 있듯이 IoC를 사용하면 프로그램을 서로 모르는 별도의 구성 요소로 분리 할 수 ​​있습니다. IoC 의 가장 일반적인 버전 중 하나 는 Dependecy Injection 입니다.

에서 의존성 삽입 (Dependency Injection) 각 구성 요소는 그것의 작업을 수행하는 데 필요한 의존성의 목록을 선언해야합니다. 런타임시 IoC 컨테이너 라고하는 특수 구성 요소 (일반적으로) 는 이러한 구성 요소 간의 바인딩을 수행합니다. 게시 된 구성 요소 종속성에 대한 값을 제공하려고합니다.

다음은 의사 코드의 예입니다.

class Foo 
{ 
   <Require Boo>Constructor(Boo boo){ boo.DoSomething } 
}

이 예제에서 클래스 Foo에는 Boo몇 가지 조치를 수행하기 위해 type 인수가 필요한 생성자가 있습니다.

다음 Foo과 비슷한 코드를 사용하여 클래스의 인스턴스를 만들 수 있습니다 .

MyContainer.Create(typeof Foo)

MyContainer-입니다 IOC는 컨테이너 의 인스턴스를 받고 처리 소요 Boo과에 전달 Foo생성자.

요약하면 IoC를 사용하면 프로그램을 별도의 부품으로 분리 할 수 ​​있습니다. 이것은 다음과 같은 이유로 좋습니다.

  • 구성 요소는 독립적으로 쉽게 테스트 할 수 있습니다.
  • 프로그램의 복잡성을 줄일 수 있습니다.
  • 컴포넌트를 다른 구현으로 전환 할 수 있습니다.

그러나 경우에 따라 IoC 는 코드를 이해하기 어렵게 만들 수 있습니다.

실제 IoC 사용의 좋은 예를 보려면 Mircosoft Composite UI Application BlockCompositeWPF를 살펴보십시오.

내 설명이 도움이 되길 바랍니다.

감사합니다,
AKU


1
5 년 후, 여전히 .... 그건 훌륭한 설명이었습니다. 감사.
Nick Hodges

4
IoC에 대한 언급이 많지 않은 것은 코드를 읽기가 더 어렵다는 사실입니다. 훌륭한 소프트웨어를 작성하려면 가독성이 최우선입니다. 심지어 테스트 가능성을 능가합니다. 유용성을 넘어서서 코드를 분리 할 수 ​​있습니다.
Arne Evertsson

따라서 모든 종속 항목에 인터페이스 기반 솔루션을 사용하는 코드는 IoC 디자인을 기반으로합니까?
nikel

18

최근 에이 문제를 파고 모든 북마크를 유지했기 때문에 다음은 IOC / DI에 대해 배우는 데 귀중한 것으로 나타났습니다.

IOC / DI에 관한 Martin Fowlers 원본 기사

먼저 알아야 할 몇 가지 개념

훌륭한 IOC / DI 튜토리얼 모음

Manning Press의 IOC / DI에 대한 예약

자신 만의 IOC를 만드는 방법에 대한 소스 및 설명 -소스 코드를 읽는 것이 항상 개념을 이해하는 가장 좋은 방법입니다.


4

JMS, 기본적으로 IoC / DI를 사용하면 한 번 사용하는 구현을 정의하고 참조 할 때마다 참조 할 수 있도록 컨테이너의 정적 사본을 유지할 수 있습니다.

Wikipedia가 도움이 될지 모르지만 두 번째 부분을 참조하고 싶었습니다. 예, 클래스에 대한 종속성 주입을 수행 할 수 있습니다 (즉,이 클래스 유형을 메소드에 전달해야 할 때 마다이 클래스를 사용하십시오). 인터페이스를 사용하면 설정에서 다시 참조하여 사용중인 제공자, 저장소 등의 버전을 변경할 수 있으므로 인터페이스를 사용하십시오.

IE는 스트림을 읽을 수있는 인터페이스가 있고 XMLStreamReader 및 SQLStreamReader 구현이 있다고 가정합니다. 그런 다음 인터페이스에 대한 참조를 메소드에 전달한 다음 IoC 컨테이너에서 사용할 것을 지정하십시오.

따라서 IStreamReader가 SQLStreamReader를 사용할 것으로 기대할 때마다 공개 List ReadPeople (IStreamReader reader)을 사용하고 IoC 컨테이너 설정에서이를 알려줄 수 있습니다.

그런 다음 나중에 마음이 바뀌면 한곳에서 변경하면됩니다 (컨테이너 설정) IStreamReader를 요청하는 메소드 수에 관계없이 항상 컨테이너에 지시 한 기본값을 얻습니다. 봉사하다.


3

비즈니스가 시스템에서 유효한지 여부를 확인하는 유효성 검사기가 있다고 가정합니다. "BusinessValidator"에는 사업장의 주소 부분을 확인하는 AddressValidator 유형의 필드가있을 수 있습니다. 외부 코드 (예 : addressValidator 코드)를 실행하지 않고 BusinessValidator를 테스트하려는 경우 프레임 워크에서 일종의 IoC / DI를 사용한 경우 모의 addressValidator를 "주입"할 수 있으며 테스트에 대해 걱정할 필요가 없습니다. 테스트중인 클래스의 범위를 벗어난 코드

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