제어 역전이란 무엇입니까?


1825

IoC (Inversion of Control)는 처음 발생할 때 매우 혼란 스러울 수 있습니다.

  1. 무엇입니까?
  2. 어떤 문제가 해결됩니까?
  3. 언제 사용하는 것이 적절합니까?

292
이러한 답변의 대부분에 대한 문제는 사용되는 용어입니다. 컨테이너 란? 전도? 의존? 큰 말없이 평신도 용어로 설명하십시오.
kirk.burleson

13
프로그래머 : SE
이즈 카타

8
그것은 의존성 주입 (DI)입니다-여기에서 Martin Fowlers의 설명을 참조하십시오 : martinfowler.com/articles/injection.html#InversionOfControl
Ricardo Sanchez


그것은 명사가 아니라 형용사가 아니며, 흐름이 제어되는 것이 컨테이너가 아닌 위임에있는 코드 변경에 대한 설명입니다.
Martin Spamer

답변:


1523

제어 반전 (IoC) 및 종속성 주입 (DI) 패턴은 코드에서 종속성을 제거하는 것입니다.

예를 들어, 응용 프로그램에 텍스트 편집기 구성 요소가 있고 철자 검사를 제공하려고한다고 가정하십시오. 표준 코드는 다음과 같습니다.

public class TextEditor {

    private SpellChecker checker;

    public TextEditor() {
        this.checker = new SpellChecker();
    }
}

우리가 여기서했던 것은 사이에 의존성 생성 TextEditor과를 SpellChecker. IoC 시나리오에서는 대신 다음과 같은 작업을 수행합니다.

public class TextEditor {

    private IocSpellChecker checker;

    public TextEditor(IocSpellChecker checker) {
        this.checker = checker;
    }
}

첫 번째 코드 예에서는 인스턴스화된다 SpellChecker( this.checker = new SpellChecker();수단되는) TextEditor클래스에 따라 직접 SpellChecker클래스.

두 번째 코드 예제에서는 SpellChecker클래스 의 종속성을 TextEditor초기화하지 않고의 생성자 서명 에 종속성 클래스 를 사용하여 추상화를 작성합니다 . 이를 통해 종속성을 호출 한 다음 TextEditor 클래스에 전달할 수 있습니다.

SpellChecker sc = new SpellChecker; // dependency
TextEditor textEditor = new TextEditor(sc);

이제 TextEditor클래스를 만드는 클라이언트 SpellCheckerTextEditor서명에 종속성을 주입하기 때문에 사용할 구현을 제어 할 수 있습니다 .


50
좋은 예입니다. 그러나 ISpellChecker 인터페이스를 객체의 생성자에 전달해야하는 대신 설정 가능한 속성 (또는 SetSpellChecker 메서드)으로 노출했습니다. 이것이 여전히 IoC를 구성합니까?
devios1

25
chainguy1337-그렇습니다. 이와 같은 세터를 사용하는 것은 생성자 주입 (종속성 주입 기술 모두)과 반대로 세터 주입이라고합니다. IoC는 상당히 일반적인 패턴이지만, 의존성 주입은 IoC를 달성합니다
Jack Ukleja

257
많은 투표권에도 불구하고이 답변은 잘못되었습니다. martinfowler.com/articles/injection.html#InversionOfControl을 참조하십시오 . 특히, "제어의 반전은 너무 일반적인 용어이므로 사람들은 혼동을 느낍니다. 결과적으로 다양한 IoC 옹호자들과 많은 토론을 통해 의존성 주입이라는 이름을 정했습니다."
Rogério

45
@Rogeria에 동의합니다. 이는 IOC의 호출되고 내가 ;-) 최대 투표의 숫자로 놀라게하고 그 이유를 설명하지 않습니다
라빈 Yarram을

31
@Rogerio 및 @Pangea와 함께합니다. 이것은 생성자 주입에 대한 좋은 예일 수 있지만 원래 질문에 대한 대답은 아닙니다. Fowler 에 의해 정의 된 IoC 는 서비스 로케이터 또는 간단한 상속 을 사용하여 어떠한 종류의 주입 없이도 실현 될 수 있습니다 .
mtsz

642

제어 반전은 GUI 프로그램과 같이 프로그램 콜백시 얻을 수있는 것입니다.

예를 들어 구식 메뉴에는 다음이있을 수 있습니다.

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

따라서 사용자 상호 작용의 흐름을 제어합니다.

GUI 프로그램 등에서 대신 다음과 같이 말합니다.

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

이제 컴퓨터는 사용자 입력을 고정 된 순서로 받아들이지 않고 데이터를 입력하는 순서와 데이터가 데이터베이스에 저장되는시기를 제어합니다.

기본적으로, 어떤 이벤트 루프는, 콜백, 또는 실행 트리거는이 범주에 빠진다.


161
이 사람을 표시하지 마십시오. 기술적으로 그는 정확합니다 martinfowler.com/bliki/InversionOfControl.html IoC는 매우 일반적인 원칙입니다. 의존성 주입은 일부 외부 시스템 (예 : IoC 컨테이너)에 효과적으로 의존성을 위임했기 때문에 제어 흐름은 의존성 주입에 의해 "반전"됩니다.
Jack Ukleja

38
슈나이더의 의견에 동의 함. 다운 보트 5 개? 이것이 정답 일 뿐이 기 때문에 마음이 흔들립니다. 오프닝에 주목하십시오 : ' gui 프로그램 처럼 .' 의존성 주입은 IoC를 가장 일반적으로 인식하는 것입니다.
Jeff Sternal

40
실제로 이것은 몇 가지 올바른 답변 중 하나입니다 ! 여러분, IoC는 근본적으로 종속성에 관한 것이 아닙니다 . 전혀.
Rogério

13
+1-Martin Fowler의 다음 문장에 대한 좋은 설명입니다 (이전의 사용자 인터페이스는 응용 프로그램으로 제어했습니다. "이름 입력", "주소 입력"과 같은 일련의 명령이 있습니다. 그래픽 (또는 화면 기반) UI를 사용하면 UI 프레임 워크에이 기본 루프가 포함되고 대신 프로그램이 화면의 다양한 필드에 대한 이벤트 처리기를 제공합니다. 프로그램이 뒤집혀서 당신에게서 틀로 옮겨졌습니다. "
Ashish Gupta

14
나는 때때로 그것이 때때로 "Hollywood Principle : 우리를 부르지 말고, 우리는 당신에게 전화 할 것"이라고
불린다.

419

제어 역전이란 무엇입니까?

이 간단한 두 단계를 따르면 제어의 반전을 수행 한 것입니다.

  1. 분리 어떤 에서 일부를 -to-할 일부를 -to이-않습니다.
  2. 있는지 확인 하면 부분으로 알고 작은 대해 가능한 어떤 부분; 그 반대.

구현에 사용중인 기술 / 언어를 기반으로 이러한 각 단계에 가능한 몇 가지 기술이 있습니다.

-

제어 반전 (IoC) 의 반전 부분은 혼란스러운 것입니다. 반전 은 상대적인 용어 이기 때문 입니다. IoC를 이해하는 가장 좋은 방법은 그 단어를 잊어 버리는 것입니다!

-

  • 이벤트 처리. 이벤트 처리기 (할일 부분)-이벤트 발생 (할일 부분)
  • 인터페이스. 컴포넌트 클라이언트 (할일 부분)-컴포넌트 인터페이스 구현 (할 일 부분)
  • xUnit 고정구. Setup 및 TearDown (할일 부분)-xUnit 프레임 워크는 처음에 Setup을 호출하고 마지막에 TearDown을 호출합니다 (할일 부분)
  • 템플릿 방법 디자인 패턴. 템플릿 메소드 할일 부분-기본 서브 클래스 구현 할일 부분
  • COM의 DLL 컨테이너 메서드 DllMain, DllCanUnload 등 (할 일 부분)-COM / OS (할 일 부분)

당신은 인터페이스를 말하는 방법. 인터페이스 (예 : 의존성 주입)를 사용할 때 컴포넌트 클라이언트 (할일 부분)가 "때"가 의미가없는 경우, 인터페이스를 추상화하고 구현을 추가하는 것에 대한 유연성을 클라이언트에게 제공하지만 "언제"는 없습니다 거기에 관여했다. 이벤트 처리 이벤트 발생시 "언제"에 동의합니다.
OldSchool

'component client'는 인터페이스의 사용자 / 클라이언트를 의미했습니다. 고객은 기능을 확장 할 것인지의 여부와 상관없이 '할 일'부분을 트리거 할 '언제'를 알고 있습니다.
rpattabi

Martin Fowler의이 훌륭한 기사를보십시오. 그는 인터페이스가 제어 역전의 기본 부분을 만드는 방법을 보여줍니다. martinfowler.com/articles/injection.html#InversionOfControl
rpattabi

두 개의 첫 문장이 훌륭합니다. 대박 !! 할 일과 할 일을 완벽하게 분리! 나는 왜 다른 답변이 그 많은 투표를 얻었는지 모른다. 이해없이 코드를 말하기 만합니다.
Amir Ziarati

2
나는 설명을 좋아 what-to-do하고when-to-do
KimchiMan

164

컨트롤 반전은 우려를 분리하는 것입니다.

IoC 미포함 : 랩톱 컴퓨터가 있고 실수로 화면을 깰 수 있습니다. 그리고, 당신은 같은 모델의 노트북 화면이 시장에서 어디에도 없다는 것을 알았습니다. 그래서 당신은 붙어 있습니다.

IoC 사용 : 데스크탑 컴퓨터가 있고 실수로 화면을 깰 수 있습니다. 당신은 시장에서 거의 모든 데스크탑 모니터를 잡을 수 있으며 데스크탑과 잘 작동합니다.

이 경우 데스크탑은 IoC를 성공적으로 구현합니다. 다양한 유형의 모니터를 사용할 수 있지만 랩톱은 그렇지 않지만 고정하려면 특정 화면이 필요합니다.


1
@Luo Jiong Hui 멋진 설명.
Sachin

3
전부는 아니더라도 대부분의 디자인 패턴은 일상 생활에서 우리가 잘보고 이해할 수있는 요소를 가지고 있습니다. 디자인 패턴을 이해하는 가장 효율적인 방법은 일상 생활 방식을 아는 것입니다. 그리고 나는 많은 것이 있다고 믿습니다.
Luo Jiong Hui

6
정답이 아닙니다. IoC가 아닌 종속성 주입을 설명 하고 있습니다. 위의 답변에 대한
MickyD

2
동의한다. 이것은 IoC가 아닌 DI입니다. 간단한 접근 방식이지만 주제에 대한 이해를 넓히는 데 도움이되기 때문에 여전히 찬성 의견을 얻습니다.
Mär

의존성 주입에 대해 설명합니다. Ioc가 아닙니다. 그러나 좋고 명확한 설명.
Chamin Wickramarathna

120

Inversion of Control (또는 IoC)은 자유얻는 것에 관한 것입니다 (결혼하고 자유를 잃고 통제를 받고 있습니다. 이혼하고 방금 Inversion of Control을 구현했습니다. 이것이 바로 "분리"된 것입니다. 스타일을 장려 매우 밀접한 관계.) 더 많은 유연성은 (사무실에 부엌은 당신이 마시고 싶어 할 때 유일한 선택입니다 깨끗한 수돗물을 제공합니다. 당신의 상사가 새로운 커피 머신을 설정하여 컨트롤의 반전을 구현했습니다. 이제 얻을 중 수돗물 또는 커피 선택의 유연성을 제공합니다.)와 덜 의존 (파트너에게는 직업이 있고, 직업이 없으며, 재정적으로 파트너에게 의존하므로, 통제됩니다. 직업을 찾고, 제어 역전을 구현했습니다. 좋은 컴퓨터 시스템은 독립성을 장려합니다.)

데스크탑 컴퓨터를 사용하면 슬레이브 (또는 제어) 상태입니다. 화면 앞에 앉아서 봐야합니다. 키보드를 사용하여 입력하고 마우스를 사용하여 탐색합니다. 잘못 작성된 소프트웨어는 더 많은 노예가 될 수 있습니다. 데스크탑을 랩톱으로 교체하면 제어가 다소 역전됩니다. 쉽게 가지고 다닐 수 있습니다. 이제 컴퓨터를 제어하는 ​​대신 컴퓨터의 현재 위치를 제어 할 수 있습니다.

Inversion of Control을 구현함으로써 소프트웨어 / 개체 소비자는 제어되거나 옵션이 적은 대신 소프트웨어 / 개체에 대해 더 많은 제어 / 옵션을 얻습니다.

위의 아이디어를 염두에두고 우리는 여전히 IoC의 핵심 부분을 그리워합니다. IoC 시나리오에서 소프트웨어 / 개체 소비자는 정교한 프레임 워크입니다. 즉, 생성 한 코드는 사용자가 직접 호출하지 않습니다. 이제이 방법이 웹 애플리케이션에 더 적합한 이유를 설명하겠습니다.

코드가 워커 그룹이라고 가정하십시오. 그들은 차를 만들어야합니다. 이 노동자들은 자동차를 만들 장소와 도구 (소프트웨어 프레임 워크)가 필요합니다. 전통적인 소프트웨어 프레임 워크는 많은 도구와 차고처럼 될 것입니다. 따라서 노동자들은 스스로 계획을 세우고 도구를 사용하여 자동차를 만들어야합니다. 차를 세우는 것은 쉬운 일이 아니므로, 노동자들이 제대로 계획하고 협력하기 란 정말 어려울 것입니다. 현대소프트웨어 프레임 워크는 모든 시설과 관리자가있는 현대 자동차 공장과 같습니다. 작업자는 계획을 세울 필요가 없으며, 관리자 (프레임 워크의 일부, 가장 똑똑한 사람들이며 가장 정교한 계획을 세운)는 작업자가 작업을 수행 할시기 (프레임 워크가 코드라고 함)를 알 수 있도록 조정하는 데 도움이됩니다. 작업자는 관리자가 자신에게 제공하는 도구를 사용할 수있을 정도로 유연해야합니다 (종속성 주입 사용).

근로자는 최상위 수준에서 프로젝트 관리 권한을 관리자에게 제공하지만 (프레임 워크). 그러나 일부 전문가의 도움을받는 것이 좋습니다. 이것이 바로 IoC의 개념입니다.

MVC 아키텍처를 사용하는 최신 웹 응용 프로그램은 URL 라우팅을 수행하고 프레임 워크를 호출 할 컨트롤러를 배치하는 프레임 워크에 의존합니다.

의존성 주입과 제어 역전은 관련이 있습니다. 의존성 주입은 마이크로 레벨에 있고 제어의 반전은 매크로 레벨에 있습니다. 식사 (구현 IoC)를 마치려면 모든 물린 (구현 DI)을 먹어야합니다.


21
나는 DI와 결혼을 비교하고 IoC와 이혼을 비교했다.
Marek Bar

"작업자들은 프로젝트 관리를 관리자 (프레임 워크)에게 최상위 수준으로 제공하지만, 일부 전문가를 도와주는 것이 좋습니다. 이것이 바로 IoC의 개념입니다."-첫째, 통제는 관리자와 함께. 그 제어가 어떻게 반전되는지 설명 할 수 있습니까? 전문가의 도움으로 (어떤 종류의 전문가)? 어떻게 ?
Istiaque Ahmed

@Istiaque Ahmed는 근로자가 모든 것을 완전히 통제 할 수있는 차고와 비교할 때 현대 자동차 공장의 관리자가 생산을 통제합니다. 따라서 이제는 통제하는 대신 노동자가 통제됩니다. 이러한 맥락에서 관리자는 근로자가 아닌 현대 자동차 공장의 일부입니다. 전문가는 자동차 계획 및 제작에 전문인 관리자입니다.
Luo Jiong Hui

2
결혼 한 사람들에게 보내는 메시지 : 지금 이혼하지 마십시오. 자녀 클래스도 IoC를 구현할 수 있습니다.
율리우스

예, 이것은 결혼에 대한 나의 비전이기도합니다. IoC
balron

94

Inversion of Control을 사용하기 전에 장단점이 있다는 사실을 잘 알고 있어야하며 사용하는 이유를 알아야합니다.

장점 :

  • 코드가 분리되어 대체 구현과 인터페이스 구현을 쉽게 교환 할 수 있습니다.
  • 구현 대신 인터페이스에 대한 코딩을위한 강력한 동기 부여
  • 생성자 / 설정자에서 허용하는 객체 외에는 아무것도 의존하지 않으므로 코드에 대한 단위 테스트를 작성하는 것이 매우 쉽고 올바른 객체를 사용하여 쉽게 초기화 할 수 있습니다.

단점 :

  • IoC는 프로그램의 제어 흐름을 반전시킬뿐만 아니라 상당히 흐려집니다. 이는 일반적으로 코드에있는 연결이 더 이상 코드에 없기 때문에 더 이상 코드를 읽고 한 곳에서 다른 곳으로 이동할 수 없음을 의미합니다. 대신 XML 구성 파일 또는 주석과 이러한 메타 데이터를 해석하는 IoC 컨테이너의 코드에 있습니다.
  • XML 구성 또는 주석이 잘못되는 새로운 버그 클래스가 발생하며 특정 조건에서 IoC 컨테이너가 객체 중 하나에 null 참조를 삽입하는 이유를 찾는 데 많은 시간을 할애 할 수 있습니다.

개인적으로 나는 IoC의 장점을 보았고 그것들을 정말로 좋아하지만 가능한 한 IoC를 피하는 경향이 있습니다. 소프트웨어가 더 이상 "실제"프로그램을 구성하는 것이 아니라 단지 하나의 프로그램으로 구성되어야하는 클래스 모음으로 바뀌기 때문입니다. XML 구성 또는 주석 메타 데이터가 없으면 XML 구성 또는 주석 메타 데이터가 분리됩니다.


3
첫 번째 죄수가 잘못되었습니다. 코드에 IOC 컨테이너를 한 번만 사용해야하는 것이 이상적이며 이것이 주요 방법입니다. 그 밖의 모든 것은 거기에서 아래로 계단식한다
mwjackson

23
나는 그가 의미하는 것은 myService.DoSomething ()을 읽고 DoSomething의 정의로 이동하는 것입니다 .IoC의 경우 myService는 인터페이스 일 뿐이므로 실제 구현은 알 수 없습니다. XML 구성 파일 또는 ioc이 설정되는 주요 방법으로 구성됩니다.
chrismay

7
Resharper가 인터페이스에 대해 "클릭하면 구현으로 이동"이 도움이됩니다. (더 구체적으로 또는 예에서 DI) IOC의를 피하는 것은 아마도 제대로 테스트하지 의미
IThasTheAnswer

10
재 : 그것은 그것없이 떨어져 결코 이상 "진짜"프로그램하지만 필요가 XML 구성 또는 주석 메타 데이터에 의해 조립되는 가을 것 (과) 폭포 것을 그냥 뭔가를 구성하는 것이 클래스의 모음으로 소프트웨어를 전환 -이 생각 매우 오도합니다. 프레임 워크 위에 작성된 모든 프로그램에 대해서도 마찬가지입니다. 좋은 IoC 컨테이너와의 차이점은 프로그램이 잘 디자인되고 작성되면 코드를 최소한으로 변경하여 다른 프로그램을 꺼내서 쓰거나 IoC를 완전히 던져 손으로 객체를 구성 할 수 있어야한다는 것입니다 .
Awnry Bear

7
이와 같은 실제 답변을 보는 것이 좋습니다! 이 "IoC"유행어가 발명되기 전에 이미 인터페이스, 팩토리 패턴, 이벤트 중심 모델 및 모의를 사용하는 객체 지향 설계 및 TDD 실습에 익숙한 숙련 된 프로그래머가 많이 있다고 생각합니다. 불행히도 너무 많은 개발자 / "건축가"는 선호하는 프레임 워크를 사용하지 않으면 나쁜 관행을 주장합니다. 나는 복잡한 디자인과 같은 동일한 목표를 달성하기 위해 더 나은 디자인, 내장 언어 개념 및 도구 사용을 선호합니다. 즉, 구현을 "흐리게"하지 않고 :-)
Tony Wall

68
  1. 위키피디아 기사 . 나에게 제어의 반전은 순차적으로 작성된 코드를 위임 구조로 바꾸는 것입니다. 프로그램이 명시 적으로 모든 것을 제어하는 ​​대신, 프로그램은 특정 일이 발생할 때 호출 할 특정 함수를 가진 클래스 또는 라이브러리를 설정합니다.

  2. 코드 중복을 해결합니다. 예를 들어, 옛날에는 새로운 이벤트에 대해 시스템 라이브러리를 폴링하여 자체 이벤트 루프를 수동으로 작성했습니다. 요즘 대부분의 최신 API는 시스템 라이브러리에 관심있는 이벤트를 알려 주면 언제 발생하는지 알려줍니다.

  3. 제어 반전은 코드 중복을 줄이는 실용적인 방법이며 전체 방법을 복사하고 작은 코드 조각 만 변경하면 제어 반전으로 처리하는 것을 고려할 수 있습니다. 델리게이트, 인터페이스 또는 원시 함수 포인터의 개념을 통해 많은 언어에서 제어 반전이 쉬워졌습니다.

    이런 방식으로 작성된 프로그램의 흐름을 따르기가 더 어려울 수 있으므로 모든 경우에 사용하는 것이 적절하지 않습니다. 재사용 할 라이브러리를 작성할 때 메소드를 설계하는 유용한 방법이지만 코드 복제 문제를 실제로 해결하지 않는 한 자체 프로그램의 핵심에서 드물게 사용해야합니다.


37
Wikipedia 기사가 매우 혼란스럽고 수정이 필요하다는 것을 알았습니다. 토론 페이지에서 웃음을 확인하십시오.
devios1

이벤트 루프가 프레임 워크를 대신하고 나머지 코드가 IoC 원칙을 사용하는 경우 자신 만의 프레임 워크를 작성한 경우 자체 이벤트 루프를 작성해도 제어가 반전 될 수 있습니다. 이것은 실제로 나쁜 것이 아니며, 조금 더 많은 코딩 가격으로 가독성을 향상시킵니다 (항상 적절하지는 않습니다).
lijat

45

하지만 조심해야한다고 생각합니다. 이 패턴을 과도하게 사용하면 매우 복잡한 디자인과 더욱 복잡한 코드를 만들 수 있습니다.

TextEditor를 사용한이 예제와 같이 SpellChecker가 하나만있는 경우 실제로 IoC를 사용할 필요는 없습니까? 단위 테스트 또는 무언가를 작성해야하는 경우가 아니면 ...

어쨌든 : 합리적이어야합니다. 디자인 패턴은 좋은 습관 이지만 설교 할 성경은 아닙니다. 어디에나 붙이지 마십시오.


3
맞춤법 검사기가 하나만 있다는 것을 어떻게 알 수 있습니까?
추적

@Trace 예를 들어 작성하려는 프로그램이 어떻게 사용되는지 알 수 있습니다. 의존성 주입과 같은 일부 기술은 너무 저렴하여 이와 같은 경우에 사용하지 않는 이유는 거의 없습니다.
lijat

44

나에게 IoC / DI는 호출 객체에 대한 의존성을 밀어 내고있다. 매우 간단합니다.

비 기술적 답변은 엔진을 켜기 직전에 자동차에서 엔진을 교체 할 수 있습니다. 모든 것이 올바르게 연결되면 (인터페이스) 좋습니다.


44

당신이 객체라고 가정하십시오. 그리고 당신은 식당에 간다 :

IoC없이 : 당신은 "사과"를 요구하고, 당신은 더 많은 것을 요청할 때 항상 사과를 제공받습니다.

IoC 사용 : "과일"을 요청할 수 있습니다. 봉사 할 때마다 다른 과일을 얻을 수 있습니다. 예를 들어 사과, 오렌지 또는 수박.

따라서 IoC는 품종을 좋아할 때 선호됩니다.


26
  1. 제어 반전은 시스템에서 구성 요소와 레이어를 분리하는 데 사용되는 패턴입니다. 패턴은 구성 요소가 구성 될 때 종속성을 구성 요소에 주입하여 구현됩니다. 이러한 종속성은 일반적으로 추가 디커플링 및 테스트 가능성을 지원하기위한 인터페이스로 제공됩니다. Castle Windsor, Unity와 같은 IoC / DI 컨테이너는 IoC를 제공하는 데 사용할 수있는 도구 (라이브러리)입니다. 이러한 도구는 수명, AOP / 차단, 정책 등을 포함하여 단순한 종속성 관리 이상의 확장 된 기능을 제공합니다.

  2. ㅏ. 구성 요소가 종속성 관리를 담당하지 않도록합니다.
    비. 다른 환경에서 종속성 구현을 교환 할 수있는 기능을 제공합니다.
    씨. 종속성을 조롱하여 구성 요소를 테스트 할 수 있습니다.
    디. 응용 프로그램 전체에서 리소스를 공유하기위한 메커니즘을 제공합니다.

  3. ㅏ. 테스트 중심 개발을 수행 할 때 중요합니다. IoC가 없으면 테스트중인 구성 요소가 나머지 시스템과 밀접하게 연결되어 있기 때문에 테스트하기가 어려울 수 있습니다.
    비. 모듈 식 시스템을 개발할 때 중요합니다. 모듈 식 시스템은 재 컴파일없이 구성 요소를 교체 할 수있는 시스템입니다.
    씨. 특히 엔터프라이즈 응용 프로그램에서 해결해야 할 여러 가지 교차 문제가있는 경우 중요합니다.


2
실제로 IoC는 주로 종속성 관리에 관한 것이 아닙니다. 자세한 내용은 martinfowler.com/articles/injection.html#InversionOfControl을 참조하십시오 . 특히 "제어의 반전은 너무 일반적인 용어이므로 사람들은 혼란스러워합니다." 의존성 주입이라는 이름으로 정했습니다. "
Rogério

26

첫 번째 부분에만 응답합니다. 무엇입니까?

IoC (Inversion of Control)는 클래스의 인스턴스를 먼저 생성 한 다음 클래스 인스턴스가 종속성의 인스턴스를 생성하는 대신 클래스의 인스턴스를 먼저 생성하고 클래스의 후자의 인스턴스를 생성 (선택적으로 생성자를 통해 주입)하는 것을 의미합니다. 따라서 제어의 반전 은 프로그램 의 제어 흐름을 반전 시킵니다 . 대신에 제어 수신자 제어의 흐름 (종속성을 생성하는 동안)에서, 호출자는 프로그램의 제어의 흐름을 제어한다 .


클래스 또는 객체 생성에 관한 것이
아니라이

22

이 두 용어에 대한 간단한 이해를 적어 두겠습니다.

For quick understanding just read examples*

의존성 주입 (DI) :
의존성 주입은 일반적으로 메소드가 종속 오브젝트를 작성하지 않고 메소드에 종속 된 메소드를 매개 변수로 메소드에 전달하는 것을 의미 합니다 .
실제로 의미는 방법이 특정 구현에 직접 의존하지 않는다는 것입니다. 요구 사항을 충족하는 모든 구현은 매개 변수로 전달 될 수 있습니다.

이 객체로 그들의 의존성을 말해줍니다. 그리고 봄은 그것을 사용할 수있게합니다.
이것은 느슨하게 결합 된 응용 프로그램 개발로 이어집니다.

Quick Example:EMPLOYEE OBJECT WHEN CREATED,
              IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT
   (if address is defines as dependency by Employee object)

IoC (Inversion of Control) 컨테이너 :
프레임 워크의 일반적인 특성으로, IOC
인스턴스화에서 BeanFactory를 통한 파괴에 이르기까지 Java 객체를 관리합니다 .
-IoC 컨테이너로 인스턴스화되는 Java 구성 요소를 Bean이라고하며 IoC 컨테이너는 Bean의 범위, 수명주기 이벤트 및 구성 및 코딩 된 AOP 기능관리합니다 .

QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it.

Inversion of Control을 구현하면 소프트웨어 / 개체 소비자는 제어되거나 옵션이 적은 대신 소프트웨어 / 개체에 대해 더 많은 제어 / 옵션을 얻을 수 있습니다.

설계 지침으로 제어를 뒤집 으면 다음과 같은 목적으로 사용됩니다.

구현에서 특정 작업의 실행을 분리합니다.
모든 모듈은 설계된 용도에 집중할 수 있습니다.
모듈은 다른 시스템의 기능에 대한 가정을하지 않고 계약에 의존합니다.
모듈을 교체해도 다른 모듈에는 부작용이 없습니다.
여기서는 요약 할 것입니다. 주제를 자세히 이해하려면 다음 링크를 방문하십시오.
예제를 잘 읽고

상해


17

NilObject에 동의 하지만 다음과 같이 추가하고 싶습니다.

전체 메소드를 복사하고 작은 코드 조각 만 변경하면 제어를 거꾸로 처리하는 것이 좋습니다.

자신이 코드를 복사하여 붙여 넣는 것을 발견하면 거의 항상 무언가 잘못하고 있습니다. 설계 원칙으로 성문화 한 번만 .


17

예를 들어, 작업 # 1은 객체를 만드는 것입니다. IOC 개념이 없으면 작업 1이 프로그래머가 수행해야하지만 IOC 개념이 있으면 작업 1이 컨테이너에 의해 수행됩니다.

간단히 말해 Control은 프로그래머에서 컨테이너로 바뀝니다. 제어의 반전이라고합니다.

여기서 좋은 예를 찾았 습니다 .


컨테이너는 IoC에서 개념 (종속성 ( "사용자"개체와 "사용 된"개체 간의 관계) 및 개체 인스턴스 포함)을 포함하여 개체 모델이 상주하고 관리되는 개념입니다. 컨테이너는 일반적으로 Spring과 같은 IoC 프레임 워크에 의해 제공됩니다. 애플리케이션을 구성하는 오브젝트의 런타임 저장소로 생각하십시오.
천막 곰

17

호텔에서 회의를한다고하자.

많은 사람들, 많은 물 한 잔, 많은 플라스틱 컵.

누군가가 마시고 싶을 때, 그녀는 컵을 채우고, 마시고 컵을 바닥에 던졌습니다.

몇 시간 후 또는 우리는 플라스틱 컵과 물로 바닥을 덮었습니다.

제어를 반전 시키십시오.

같은 장소에서 같은 모임이지만 플라스틱 컵 대신 유리 컵 (싱글 톤)이있는 웨이터가 있습니다.

그리고 그녀는 항상 손님에게 술을 제공합니다.

누군가 마시고 싶을 때 웨이터 유리에서 나와서 다시 웨이터에게 돌려줍니다.

위생적인 문제를 제쳐두고, 마지막 형태의 음주 공정 제어는 훨씬 더 효과적이고 경제적입니다.

이것이 바로 Spring (예 : 다른 IoC 컨테이너, Guice)의 기능입니다. Spring IoC 컨테이너는 항상 새로운 키워드 (플라스틱 컵 사용)를 사용하여 필요한 것을 만들도록하는 대신 필요한 객체 (물 유리)의 동일한 인스턴스 (단일)를 적용 할 수 있도록 항상 제공합니다.

그러한 모임의 주최자로서 자신을 생각하십시오. 호텔 관리에게 메시지를 보내는 방법이 필요합니다.

회의 회원은 물 한 잔이 필요하지만 케이크 조각은 필요하지 않습니다.

예:-

public class MeetingMember {

    private GlassOfWater glassOfWater;

    ...

    public void setGlassOfWater(GlassOfWater glassOfWater){
        this.glassOfWater = glassOfWater;
    }
    //your glassOfWater object initialized and ready to use...
    //spring IoC  called setGlassOfWater method itself in order to
    //offer to meetingMember glassOfWater instance

}

유용한 링크:-


정적 타입 객체가 아닌가?
Gokigooooks

16

"IoC"에 대해 가장 혼동되는 것은 약어와 그 이름의 이름이 너무 매력적이어서 거의 소음이없는 것입니다.

절차 적 프로그래밍과 이벤트 중심 프로그래밍의 차이점을 설명 할 수있는 이름이 정말로 필요합니까? 우리가 필요로한다면 문제보다 더 혼란스러운 새로운 "생명보다 더 큰"이름을 선택해야합니까?


1
IoC! = 이벤트 기반. 유사점 (일부 경우 겹치기)이지만 기본적으로 동일한 패러다임은 아닙니다.
Awnry Bear

좋은 질문. 이벤트 중심 프로그래밍은 확실히 IoC입니다. 이벤트 핸들러를 작성하고 이벤트 루프에서 호출됩니다. 그러나 IoC는 이벤트 중심 프로그래밍보다 일반적인 개념입니다. 하위 클래스의 메서드를 재정의하는 경우 IoC의 일종이기도합니다. 적절한 참조 (인스턴스)가 사용될 때 호출 될 코드를 작성합니다.
vi.su.

15

제어 역전 당신이 식료품 가게에 가서 당신의 아내는 당신이 구입하는 제품의 목록을 제공 할 때입니다.

프로그래밍 용어로 콜백 함수 getProductList()를 실행중인 함수 에 전달했습니다.doShopping() .

함수의 사용자가 함수의 일부를 정의 할 수있어보다 유연합니다.


5
아내는 대개 나와 함께 쇼핑하지만이 진술에 동의합니다.
ha9u63ar

1
아내가 당신과 함께 가게? 그렇다면 그것은 집계라고 불립니다.
율리우스

2
그녀가 돈을 주면 DI라고합니다.
San

1
반전이라는 단어는 부인 getProductList()이 돈의 원천을 찾아야 할 때 통제가 당신 편이라는 것을 의미합니다. 반전의 경우, 그녀는 통제 할 것이며, 그녀는 또한 구매를 위해 제공 할 돈을 의미합니다.
San

13

여기서 '제어가 반전되는 방법'을 설명하는 매우 명확한 예를 찾았습니다 .

클래식 코드 (종속성 주입 없음)

DI를 사용하지 않는 코드가 대략적으로 작동하는 방법은 다음과 같습니다.

  • 응용 프로그램에는 Foo (예 : 컨트롤러)가 필요합니다.
  • 응용 프로그램이 Foo를 만듭니다
  • 응용 프로그램 호출 Foo
    • Foo에는 Bar (예 : 서비스)가 필요합니다.
    • 푸는 바를 만듭니다
    • 푸 콜 바
      • Bar는 Bim (서비스, 저장소 등)이 필요하므로 다음과 같이하십시오.
      • 바는 Bim을 만듭니다
      • 바 뭔가를

의존성 주입 사용

DI를 사용하는 코드가 대략적으로 작동하는 방법은 다음과 같습니다.

  • 응용 프로그램에는 Foo가 필요하고 Bar가 필요하고 Bim이 필요합니다.
  • 응용 프로그램이 Bim을 만듭니다
  • 응용 프로그램은 막대를 만들어 Bim을 제공합니다.
  • 응용 프로그램이 Foo를 작성하고이를 제공합니다.
  • 응용 프로그램 호출 Foo
    • 푸 콜 바
      • 바 뭔가를

종속성의 제어는 호출되는 호출에서 호출되는 호출로 반전됩니다.

어떤 문제가 해결됩니까?

의존성 주입을 통해 주입 된 클래스의 다른 구현으로 쉽게 교체 할 수 있습니다. 단위 테스트를 수행하는 동안 더미 구현을 삽입 할 수 있으므로 테스트가 훨씬 쉬워집니다.

예 : 애플리케이션이 사용자가 업로드 한 파일을 Google 드라이브에 저장한다고 가정하면 DI와 함께 컨트롤러 코드는 다음과 같습니다.

class SomeController
{
    private $storage;

    function __construct(StorageServiceInterface $storage)
    {
        $this->storage = $storage;
    }

    public function myFunction () 
    {
        return $this->storage->getFile($fileName);
    }
}

class GoogleDriveService implements StorageServiceInterface
{
    public function authenticate($user) {}
    public function putFile($file) {}
    public function getFile($file) {}
}

요구 사항이 변경되면 GoogleDrive 대신 Dropbox를 사용해야합니다. StorageServiceInterface에 대한 드롭 박스 구현 만 작성하면됩니다. Dropbox 구현이 StorageServiceInterface를 준수하는 한 컨트롤러를 변경하지 않아도됩니다.

테스트하는 동안 모든 메소드가 널 (또는 테스트 요구 사항에 따라 사전 정의 된 값)을 리턴하는 더미 구현으로 StorageServiceInterface에 대한 모의를 작성할 수 있습니다.

대신 다음과 같이 new키워드를 사용 하여 스토리지 오브젝트를 구성하는 컨트롤러 클래스가있는 경우 :

class SomeController
{
    private $storage;

    function __construct()
    {
        $this->storage = new GoogleDriveService();
    }

    public function myFunction () 
    {
        return $this->storage->getFile($fileName);
    }
}

Dropbox 구현으로 변경하려면 newGoogleDriveService 객체가 생성 된 모든 줄을 바꾸고 DropboxService를 사용해야합니다. SomeController 클래스를 테스트 할 때 생성자는 항상 GoogleDriveService 클래스를 기대하고이 클래스의 실제 메소드가 트리거됩니다.

적절한시기와시기는? 내 생각에 당신은 클래스의 대체 구현이 있거나있을 수 있다고 생각할 때 DI를 사용합니다.


이것은 "제어"가 어떻게 반전되는지를 설명하는 유일한 대답이므로 가장 정확한 답이되어야합니다.
Yarimadam

지금까지 가장 좋은 설명
Ali80

12

매우 간단한 서면 설명은 여기에서 찾을 수 있습니다

http://binstock.blogspot.in/2008/01/excellent-explanation-of-dependency.html

그것은 말한다-

"모든 사소한 응용 프로그램은 비즈니스 로직을 수행하기 위해 서로 협력하는 둘 이상의 클래스로 구성됩니다. 일반적으로 각 개체는 공동 작업하는 개체 (종속성)에 대한 자체 참조를 가져옵니다. DI를 적용 할 때는 객체는 시스템의 각 객체를 조정하는 외부 엔티티에 의해 생성 시점에 종속성이 부여됩니다. 즉, 종속성은 객체에 주입됩니다. "


12

Control of Inversion은 일반적인 원칙이며, Dependency Injection은이 원칙을 객체 그래프 구성을위한 디자인 패턴으로 인식합니다 (예 : 구성은 객체 자체가 다른 객체에 대한 참조를 얻는 방법을 제어하는 ​​것이 아니라 객체가 서로를 참조하는 방식을 제어합니다).

Inversion of Control을 디자인 패턴으로보고, 우리가 뒤집는 것을 살펴 봐야합니다. 의존성 주입은 객체의 그래프 구성 제어를 반전시킵니다. 평신도의 용어로 말하면 제어의 반전은 프로그램의 제어 흐름의 변화를 의미합니다. 예 : 기존의 독립형 앱에는 컨트롤이 다른 타사 라이브러리로 전달되는 주요 방법이 있지만 (타사 라이브러리 기능을 사용하는 경우) 제어 제어의 반전을 통해 타사 라이브러리 코드에서 코드로 전송됩니다. , 제 3 자 도서관 서비스를 받고 있습니다. 그러나 프로그램 내에서 반전되어야하는 다른 측면들 (예 : 코드를 실행하기위한 메소드 및 스레드 호출)이 있습니다.

Inversion of Control에 대해 더 깊이 관심이있는 사람들을 위해 디자인 패턴으로서 Control of Inversion에 대한보다 완전한 그림을 요약 한 논문이 발표되었습니다 (OfficeFloor : 사무실 패턴을 사용하여 소프트웨어 디자인 개선 http://doi.acm.org/10.1145/ http://www.officefloor.net/about.html 에서 무료로 다운로드 할 수있는 2739011.2739013 ).

식별되는 것은 다음 관계입니다.

제어 역전 (방법의 경우) = 종속성 (상태) 주입 + 연속 주입 + 스레드 주입

사용 가능한 제어 역전에 대한 위의 관계 요약-http: //dzone.com/articles/inversion-of-coupling-control


이것은 매우 명확한 대답입니다. 설명 주셔서 감사합니다.
KunYu Tsai

11

IoC는 코드와 타사 코드 (라이브러리 / 프레임 워크) 간의 관계를 반전시키는 것입니다.

  • 일반적인 소프트웨어 개발에서는 main () 메소드 를 작성하고 "library"메소드를 호출합니다. 당신 은 통제하고 있습니다 :)
  • IoC에서 "프레임 워크"는 main ()을 제어 하고 메소드를 호출합니다. 프레임 워크는 컨트롤에 :(

DI (Dependency Injection)는 응용 프로그램에서 컨트롤의 흐름에 관한 것입니다. 전통적인 데스크톱 응용 프로그램은 응용 프로그램 (main () 메서드)에서 다른 라이브러리 메서드 호출로 제어 흐름을 가졌지 만 DI 제어 흐름을 거꾸로하면 프레임 워크가 앱을 시작하고 초기화하고 필요할 때마다 메서드를 호출합니다.

결국 당신은 항상 승리 :)


10

나는이 설명을 좋아한다 : http://joelabrahamsson.com/inversion-of-control-an-introduction-with-examples-in-net/

간단하게 시작하고 코드 예제도 보여줍니다.

여기에 이미지 설명을 입력하십시오

소비자 X는 무언가를 달성하기 위해 소비 클래스 Y가 필요합니다. 그것은 모두 좋고 자연 스럽지만 X는 실제로 Y를 사용한다는 것을 알아야합니까?

X가 누가 실제로 행동을 구현하는지 모르면서 Y의 행동, 방법, 속성 등을 가진 것을 사용한다는 것을 X가 아는 것만으로는 충분하지 않습니까?

아래 I과 같이 Y에서 X가 사용하는 동작에 대한 추상 정의를 추출하고 소비자 X가 Y 대신 해당 인스턴스를 사용하게하면 Y에 대한 세부 사항을 알 필요없이 계속 수행 할 수 있습니다.

여기에 이미지 설명을 입력하십시오

위의 그림에서 Y는 I을 구현하고 X는 I의 인스턴스를 사용합니다. X가 여전히 Y를 사용하는 것이 가능하지만 흥미로운 것은 X가 그것을 모르는 것입니다. 그것은 내가 그것을 구현하는 것을 사용한다는 것을 알고 있습니다.

다음과 같은 이점에 대한 자세한 정보 및 설명은 기사를 읽으십시오.

  • X는 더 이상 Y에 의존하지 않습니다
  • 런타임에서보다 유연한 구현을 결정할 수 있습니다.
  • 코드 단위의 분리, 쉬운 테스트

...


이 링크는 매우 도움이됩니다. 정말 감사합니다 :)
M Fuat NUROĞLU

10

답변이 이미 여기에 있음을 이해합니다. 그러나 나는 여전히 미래의 독자들을 위해 통제 역전에 대한 몇 가지 기본 사항에 대해 오랫동안 논의해야한다고 생각합니다.

IoC (Inversion of Control)는 Hollywood Principle 이라는 매우 간단한 원칙을 기반으로 구축되었습니다 . 그리고 그것은 말합니다.

전화 하지마, 전화 할께

의미는 당신이 합당하다면 꿈을 이루기 위해 할리우드에 가지 않는 것입니다. 할리우드는 당신을 찾고 꿈을 이룰 것입니다. 거꾸로 된 거지?

이제 우리는 IoC의 원칙에 대해 논의 할 때 할리우드를 잊어 버리기 위해 사용합니다. IoC를 위해서는 할리우드, 당신, 그리고 당신의 꿈을 이루기위한 과제의 세 가지 요소가 있어야합니다.

프로그래밍 세계에서 Hollywood 는 일반적인 프레임 워크 (귀하 또는 다른 사람이 작성할 수 있음) 나타내며, 작성한 사용자 코드 및 작업 나타냅니다. 나타내며 은 코드로 수행하려는 것을 나타냅니다. 이제 IoC가 아닌 혼자서 작업을 시작하지 않아도됩니다. 오히려 프레임 워크가 작업을 트리거하도록 모든 것을 설계했습니다. 따라서 누군가를 영웅이나 다른 사람으로 만들 수있는 재사용 가능한 프레임 워크를 만들었습니다. 그러나 그 프레임 워크는 항상 책임이 있으며, 누군가를 고를 때를 알고 누군가가 자신이 원하는 것을 알고 있다는 것을 압니다.

실제 사례가 여기에 주어질 것입니다. 웹 애플리케이션을 개발하려고한다고 가정하십시오. 따라서 웹 응용 프로그램이 http 요청 처리, 응용 프로그램 메뉴 생성, 페이지 제공, 쿠키 관리, 이벤트 트리거 등과 같이 웹 응용 프로그램이 처리해야하는 모든 공통 사항을 처리하는 프레임 워크를 만듭니다.

그런 다음 프레임 워크에 후크를 남겨서 사용자 정의 메뉴, 페이지, 쿠키를 생성하거나 일부 사용자 이벤트 등을 생성하는 추가 코드를 넣을 수 있습니다. 모든 브라우저 요청에서 프레임 워크가 실행되면 사용자 정의 코드가 실행되고 다시 실행됩니다. 브라우저에.

아이디어는 매우 간단합니다. 모든 것을 제어하는 ​​사용자 응용 프로그램을 만드는 대신 먼저 모든 것을 제어하는 ​​재사용 가능한 프레임 워크를 만든 다음 사용자 지정 코드를 작성하여 프레임 워크에 연결하여 제 시간에 실행되도록하십시오.

라 라벨과 EJB가 그러한 프레임 워크의 예입니다.

참고:

https://martinfowler.com/bliki/InversionOfControl.html

https://ko.wikipedia.org/wiki/Inversion_of_control


1
내가 찾은 가장 적절한 대답.
blueray

8

프로그래밍 말하기

쉬운 용어로 IoC : 인터페이스를 특정 클래스 (예 : 필드 또는 매개 변수)로 와일드 카드로 사용하여 일부 클래스에서 사용할 수 있습니다. 코드를 재사용 할 수 있습니다.

예를 들어 두 개의 클래스가 있다고 가정 해 봅시다. DogCat의 . 둘 다 같은 질 / 상태를 공유합니다 : 나이, 크기, 체중. 따라서 DogServiceCatService 라는 서비스 클래스를 작성하는 대신 IAnimal 인터페이스를 사용하는 경우에만 Dog 및 Cat을 사용할 수있는 AnimalService 라는 단일 클래스를 작성할 수 있습니다 .

그러나 실용적으로 말하면 약간 뒤로 향합니다.

a) 대부분의 개발자들은 그것을 사용하는 방법을 모른다 . 예를 들어, 나는라는 클래스 만들 수 있습니다 고객내가 자동으로 생성 할 수 있습니다 라는 인터페이스 (IDE의 도구 사용) ICustomer을 . 따라서 인터페이스의 재사용 여부에 관계없이 클래스와 인터페이스로 채워진 폴더를 찾는 것은 드문 일이 아닙니다. BLOATED라고합니다. 어떤 사람들은 "나중에 우리가 그것을 사용할 수 있을지도 모른다"고 주장 할 수 있습니다. :-|

b) 한계가있다. 예를 들어, Dog and Cat 의 경우에 대해 이야기하고 에만 새로운 서비스 (기능)를 추가하고 싶습니다. 내가 개를 훈련시키는 데 필요한 일 수를 계산하고 싶다고 가정 해 봅시다 ( trainDays()). 고양이는 쓸모가 없으며 고양이를 훈련시킬 수 없습니다 (농담 중).

b.1) trainDays()서비스 AnimalService에 추가 하면 고양이와도 작동하며 전혀 유효하지 않습니다.

b.2) trainDays()어떤 클래스가 사용되는지 평가 하는 조건을 추가 할 수 있습니다 . 그러나 그것은 완전히 IoC를 망칠 것입니다.

b.3) 새로운 기능을 위해 DogService 라는 새로운 서비스 클래스를 만들 수 있습니다 . 그러나 Dog에 대해 두 가지 서비스 클래스 (유사한 기능)가 있고 코드가 나쁘기 때문에 코드 유지 관리 성이 향상됩니다 .


확장 클래스 / 인터페이스 정보 : 모든 단일 인터페이스를 항상 재사용 할 필요는 없습니다. 때로는 기능적 경계를보기 위해 큰 인터페이스를 여러 개의 작은 인터페이스로 분할하는 것이 합리적입니다. 더 작은 인터페이스는 다른 구현에서도 재사용하기가 더 쉽습니다. 또한 인터페이스가 의미가있는 곳이라면 어디든지 인터페이스로 코딩하도록 권장합니다. "인터페이스 분리"를 고려하십시오. 인터페이스를 사용한다고해서 분리 된 것은 아닙니다. 단일 지방 인터페이스는 쓸모가 없습니다. -그냥 내 2 센트 :)
MK

7

나는 이것에 대한 많은 답변을 읽었지만 누군가가 여전히 혼란스럽고 여기에 IoC를 설명하기 위해 플러스 "레이맨 용어"가 필요하다면 여기 내 테이크입니다.

부모와 자녀가 서로 이야기한다고 상상해보십시오.

IoC없이 :

*부모의 : 질문 할 때만 말할 수 있고 허락 할 때만 행동 할 수 있습니다.

부모 : 이것은 당신이 나에게 물어 보지 않으면 먹고, 놀고, 화장실에 가거나, 심지어 잠을 잘 수 있는지 나에게 물어볼 수 없다는 것을 의미합니다.

부모 : 먹고 싶니?

아동 : 아니오

부모 : 좋아, 돌아올 게. 날 기다려.

Child : (놀이를하고 싶지만 부모로부터 의심의 여지가 없으므로 아이는 아무것도 할 수 없습니다).

1 시간 후에...

부모 : 돌아 왔어요. 당신이 연주하고 싶어?

아이 : 예.

부모 : 권한 부여.

어린이 : (마지막으로 재생할 수 있습니다).

이 간단한 시나리오는 컨트롤이 부모를 중심으로 설명합니다. 자녀의 자유는 제한되어 있으며 부모의 질문에 크게 의존합니다. 아동은 발언 요청이있을 때만 발언 할 수 있으며 허가가있을 때만 행동 할 수 있습니다 .

IoC로 :

자녀는 이제 질문을 할 수 있으며 부모는 답변과 허락으로 응답 할 수 있습니다. 간단히 컨트롤이 반전되었음을 의미합니다! 이제 자녀는 언제든지 질문을 자유롭게 할 수 있으며 허가와 관련하여 여전히 부모와의 의존 관계는 있지만 질문을하거나 말하는 방법에는 의존하지 않습니다.

기술적으로 설명하면 콘솔 / 쉘 / cmd 대 GUI 상호 작용과 매우 유사합니다. (마크 해리슨의 답변은 2 위의 최고 답변입니다). 콘솔에서, 당신은 당신에게 요청 / 표시되는 것에 의존하며, 먼저 질문에 대답하지 않고 다른 메뉴와 기능으로 이동할 수 없습니다; 엄격한 순차적 흐름을 따릅니다. (프로그래밍 방식은 메소드 / 함수 루프와 같습니다). 그러나 GUI를 사용하면 메뉴와 기능이 배치되고 사용자는 필요한 것을 선택할 수 있으므로 더 많은 제어 와 제한을받지 않아도 됩니다. 프로그래밍 방식으로 메뉴를 선택하면 콜백이 발생하고 작업이 수행됩니다.


6

제어의 반전은 라이브러리에서 클라이언트로 제어를 전송하는 것입니다. 함수 값 (람다 식)을 라이브러리 함수의 동작을 제어 (변경)하는 상위 함수 (라이브러리 함수)에 삽입 (전달)하는 클라이언트에 대해 이야기하는 것이 더 합리적입니다. 라이브러리 의존성 (동작을 수행하는)을 라이브러리에 주입하는 클라이언트 또는 프레임 워크도 IoC로 간주 될 수 있습니다.


5

이미 질문에 대한 많은 답변이 있지만 그중 어느 것도 반전 제어 용어의 고장을 보여주지 않습니다. 더 간결하고 유용한 답변을 줄 수있는 기회를 봅니다.

Inversion of Control은 DIP (Dependency Inversion Principle)를 구현하는 패턴입니다. DIP는 다음을 나타냅니다. 1. 높은 수준의 모듈은 낮은 수준의 모듈에 의존해서는 안됩니다. 둘 다 추상화 (예 : 인터페이스)에 의존해야합니다. 2. 추상화는 세부 사항에 의존해서는 안됩니다. 세부 사항 (콘크리트 구현)은 추상화에 따라 달라집니다.

Inversion of Control에는 세 가지 유형이 있습니다.

Interface Inversion Providers는 인터페이스를 정의하지 않아야합니다. 대신 소비자는 인터페이스를 정의해야하며 공급자는이를 구현해야합니다. Interface Inversion을 사용하면 새로운 공급자를 추가 할 때마다 소비자를 수정할 필요가 없습니다.

흐름 반전 흐름 제어를 변경합니다. 예를 들어, 많은 매개 변수를 입력하도록 요청한 콘솔 응용 프로그램이 있으며 입력 한 각 매개 변수 다음에 Enter 키를 눌러야합니다. 여기서 Flow Inversion을 적용하고 사용자가 매개 변수 입력 순서를 선택할 수 있고 사용자가 매개 변수를 편집 할 수 있으며 마지막 단계에서 Enter를 한 번만 눌러야하는 데스크탑 애플리케이션을 구현할 수 있습니다.

Creation Inversion 공장 패턴, 서비스 로케이터 및 종속성 주입 패턴으로 구현할 수 있습니다. Creation Inversion은 종속성 개체의 프로세스를 이러한 종속성 개체를 사용하는 형식 외부로 이동시키는 형식 간의 종속성을 제거하는 데 도움이됩니다. 종속성이 나쁜 이유는 무엇입니까? 다음은 몇 가지 예입니다. 코드에서 새 객체를 직접 작성하면 테스트가 더 어려워집니다. 재 컴파일없이 어셈블리에서 참조를 변경하는 것은 불가능합니다 (OCP 원칙 위반). 데스크탑 UI를 웹 UI로 쉽게 대체 할 수 없습니다.


3
  1. 위의 1 번 . 제어 역전이란 무엇입니까?

  2. 유지 보수는 나를 위해 해결하는 가장 중요한 것입니다. 두 클래스가 서로 친밀하지 않도록 인터페이스를 사용하고 있음을 보장합니다.

Castle Windsor와 같은 컨테이너를 사용하면 유지 관리 문제를 훨씬 더 잘 해결합니다. 코드 행을 변경하지 않고 파일 기반 지속성을 사용하는 구성 요소를 데이터베이스로 이동하는 구성 요소를 교체 할 수 있다는 것은 대단합니다 (구성 변경이 완료되었습니다).

그리고 일단 제네릭에 들어가면 더 좋아집니다. 레코드를 받고 메시지를 게시하는 메시지 게시자가 있다고 가정합니다. 게시하는 내용은 중요하지 않지만 레코드에서 메시지로 무언가를 가져 오려면 매퍼가 필요합니다.

public class MessagePublisher<RECORD,MESSAGE>
{
    public MessagePublisher(IMapper<RECORD,MESSAGE> mapper,IRemoteEndpoint endPointToSendTo)
    {
      //setup
    }
}

한 번 작성했지만 다른 유형의 메시지를 게시하면이 코드 세트에 여러 유형을 삽입 할 수 있습니다. 또한 같은 유형의 레코드를 가져와 다른 메시지에 매핑하는 매퍼를 작성할 수 있습니다. DI를 Generics와 함께 사용하면 많은 작업을 수행하기 위해 코드를 거의 작성할 수 없습니다.

예, 테스트 가능성 문제가 있지만 IoC / DI의 이점에 부차적입니다.

나는 IoC / DI를 확실히 좋아합니다.

삼 . 다소 규모가 더 복잡한 중간 규모의 프로젝트가있을 때 더 적합합니다. 나는 당신이 고통을 느끼기 시작하는 순간 그것이 적절 해 진다고 말할 것입니다.



3

클래스 내에 객체를 생성하는 것을 타이트 커플 링이라고하며 Spring은 디자인 패턴 (DI / IOC)에 따라 이러한 종속성을 제거합니다. 클래스에서 만들지 않고 생성자가 전달한 클래스의 객체. 또한 더 일반적인 구조를 정의하기 위해 생성자에 슈퍼 클래스 참조 변수를 제공합니다.

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