etc./StackOverFlow

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

청렴결백한 만능 재주꾼 2021. 12. 4. 10:39
반응형

질문자 :Mike Minutillo


IoC(Inversion of Control)는 처음 접했을 때 상당히 혼란스러울 수 있습니다.

  1. 그것은 무엇입니까?
  2. 어떤 문제를 해결합니까?
  3. 언제 사용하는 것이 적절하고 언제 사용하지 않는 것이 적절합니까?


IoC(Inversion of Control) 및 DI(Dependency Injection) 패턴은 모두 코드에서 종속성을 제거하는 것입니다.

예를 들어 응용 프로그램에 텍스트 편집기 구성 요소가 있고 맞춤법 검사를 제공하려고 한다고 가정해 보겠습니다. 표준 코드는 다음과 같습니다.

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

TextEditorSpellChecker 사이에 종속성을 생성합니다. IoC 시나리오에서는 대신 다음과 같이 합니다.

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

첫 번째 코드 예제에서는 SpellChecker 를 인스턴스화하고 있습니다( this.checker = new SpellChecker(); TextEditor SpellChecker 클래스에 직접적으로 의존함을 의미합니다.

TextEditor SpellChecker 종속성 클래스를 사용하여 추상화를 만들고 있습니다(클래스에서 종속성을 초기화하지 않음). 이렇게 하면 종속성을 호출한 다음 다음과 같이 TextEditor 클래스에 전달할 수 있습니다.

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

TextEditor 클래스를 생성하는 클라이언트 TextEditor 서명에 종속성을 주입하기 때문에 사용할 SpellChecker


urini

Inversion of Control은 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

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

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


Mark Harrison

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

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

  1. 일부 -to이-할 때부터 부분을 -to-무엇을 분리합니다.
  2. 확인 부분은 어떤 부분에 대해 가능한 한 적게 알고있는 때; 그 반대.

구현에 사용하는 기술/언어에 따라 이러한 각 단계에 몇 가지 기술이 가능합니다.

--

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

--

  • 이벤트 처리. 이벤트 핸들러(할 일 부분) -- 이벤트 발생(해야 할 일 부분)
  • 의존성 주입. 종속성을 구성하는 코드(할 일 부분) -- 필요할 때 클라이언트를 위해 해당 종속성을 인스턴스화하고 주입합니다. 이는 일반적으로 Dagger(때 수행 부분)와 같은 DI 도구에서 처리합니다.
  • 인터페이스. 구성 요소 클라이언트(때 수행 부분) -- 구성 요소 인터페이스 구현(해야 할 작업 부분)
  • xUnit 고정 장치. 설정 및 TearDown(해야 할 일 부분) -- xUnit 프레임워크는 시작 부분에서 Setup을 호출하고 끝 부분에서 TearDown(해야 할 일 부분)을 호출합니다.
  • 템플릿 메서드 디자인 패턴입니다. 템플릿 메소드 언제 할 일 부분 -- 기본 서브클래스 구현 할 일 부분
  • COM의 DLL 컨테이너 메서드 DllMain, DllCanUnload 등(할 일 부분) -- COM/OS(해야 할 일 부분)

rpattabi

Inversion of Controls는 관심사를 분리하는 것입니다.

IoC가 없는 경우 : 랩톱 컴퓨터가 있고 실수로 화면이 깨졌습니다. 그리고 젠장, 같은 모델의 노트북 화면은 시장 어디에도 없습니다. 그래서 당신은 붙어 있습니다.

IoC 사용 : 데스크탑 컴퓨터가 있고 실수로 화면이 깨졌습니다. 시장에서 거의 모든 데스크탑 모니터를 구입할 수 있으며 데스크탑과 잘 작동합니다.

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


Luo Jiong Hui

Inversion of Control(또는 IoC)은 자유를 얻는 것입니다. (결혼하면 자유를 잃고 통제당합니다. 이혼하고 방금 Inversion of Control을 구현했습니다. 이것이 우리가 "분리"라고 부르는 것입니다. 좋은 컴퓨터 시스템 매우 가까운 관계를 권장하지 않습니다.) 더 많은 유연성 (사무실의 주방은 깨끗한 수돗물만 제공합니다. 마시고 싶을 때 선택할 수 있는 유일한 방법입니다. 상사는 새 커피 머신을 설치하여 제어의 역전을 구현했습니다. 이제 당신은 수돗물 또는 커피를 선택할 수 있는 유연성) 및 덜 의존적 통제: 좋은 컴퓨터 시스템은 독립성을 조장합니다.)

데스크탑 컴퓨터를 사용하는 경우 종속(또는 제어)됩니다. 스크린 앞에 앉아서 봐야 합니다. 키보드를 사용하여 입력하고 마우스를 사용하여 탐색합니다. 그리고 잘못 작성된 소프트웨어는 더 많은 노예가 될 수 있습니다. 데스크탑을 랩탑으로 바꾸면 제어가 다소 역전됩니다. 쉽게 가져가서 이동할 수 있습니다. 이제 컴퓨터가 컴퓨터를 제어하는 대신 컴퓨터를 사용하여 현재 위치를 제어할 수 있습니다.

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

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

코드가 작업자 그룹이라고 가정합니다. 그들은 자동차를 만들어야 합니다. 이 작업자들은 자동차를 만들기 위한 장소와 도구(소프트웨어 프레임워크)가 필요합니다. 전통적인 소프트웨어 프레임워크는 많은 도구가 있는 차고와 같습니다. 따라서 작업자가 직접 계획을 세우고 도구를 사용하여 자동차를 만들어야 합니다. 자동차를 만드는 것은 쉬운 일이 아니며 작업자가 제대로 계획하고 협력하기가 정말 어려울 것입니다. 현대식 소프트웨어 프레임워크는 모든 시설과 관리자가 있는 현대식 자동차 공장과 같습니다. 작업자는 계획을 세울 필요가 없습니다. 관리자(프레임워크의 일부, 그들은 가장 똑똑한 사람들이며 가장 정교한 계획을 세웠습니다)는 작업자가 언제 작업을 수행해야 하는지 알 수 있도록 조정하는 데 도움을 줄 것입니다(프레임워크가 코드를 호출함). 작업자는 관리자가 제공하는 모든 도구(종속성 주입 사용)를 사용할 수 있을 만큼 충분히 유연하면 됩니다.

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

MVC 아키텍처를 사용하는 최신 웹 애플리케이션은 URL 라우팅을 수행하고 프레임워크가 호출할 컨트롤러를 제자리에 배치하는 프레임워크에 의존합니다.

종속성 주입과 제어 역전은 관련이 있습니다. 종속성 주입은 미시적 수준에 있고 제어 역전은 거시적 수준에 있습니다. 식사를 마치려면(IoC를 구현) 한 입씩 먹어야 합니다(DI 구현).


Luo Jiong Hui

Inversion of Control을 사용하기 전에 장단점이 있다는 사실을 잘 알고 있어야 하며 그렇게 할 경우 왜 사용하는지 알아야 합니다.

장점:

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

단점:

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

개인적으로 IoC의 장점을 보고 정말 좋아하지만 IoC를 사용하면 소프트웨어가 더 이상 "실제" 프로그램을 구성하지 않고 XML 구성 또는 주석 메타데이터가 없으면 분리됩니다.


ahe

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

  2. 코드 중복을 해결합니다. 예를 들어, 예전에는 새로운 이벤트에 대해 시스템 라이브러리를 폴링하여 고유한 이벤트 루프를 수동으로 작성했습니다. 오늘날 대부분의 최신 API는 시스템 라이브러리에 관심 있는 이벤트를 알려주기만 하면 이벤트가 발생하면 알려줍니다.

  3. 제어 역전은 코드 중복을 줄이는 실용적인 방법이며 전체 메서드를 복사하고 코드의 작은 부분만 변경하는 경우 제어 역전으로 문제를 해결할 수 있습니다. 제어 역전은 대리자, 인터페이스 또는 원시 함수 포인터의 개념을 통해 많은 언어에서 쉽게 이루어집니다.

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


NilObject

당신이 개체라고 가정합니다. 그리고 식당에 갑니다.

IoC 없이 : "사과"를 요청하고 더 많이 요청할 때 항상 사과가 제공됩니다.

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

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


Luo Jiong Hui

그러나 나는 당신이 그것에 대해 매우 조심해야한다고 생각합니다. 이 패턴을 남용하면 디자인이 매우 복잡해지고 코드가 훨씬 더 복잡해집니다.

TextEditor가 있는 이 예에서처럼: SpellChecker가 하나만 있으면 IoC를 사용할 필요가 없을 수도 있습니다. 단위 테스트를 작성해야 하는 경우가 아니면 ...

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


Michal Sznajder

나에게 IoC / DI는 호출 개체에 대한 종속성을 밀어내고 있습니다. 매우 간단합니다.

기술이 아닌 대답은 자동차의 시동을 켜기 직전에 엔진을 교체할 수 있다는 것입니다. 모든 것이 올바르게 연결되면(인터페이스) 정상입니다.


ferventcoder

첫 번째 부분만 답변합니다. 그것은 무엇입니까?

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


user2330678

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

  2. NS. 구성 요소가 종속성을 관리하는 책임을 덜어줍니다.
    NS. 다양한 환경에서 종속성 구현을 교환하는 기능을 제공합니다.
    씨. 종속성 모의를 통해 구성 요소를 테스트할 수 있습니다.
    NS. 애플리케이션 전체에서 리소스를 공유하기 위한 메커니즘을 제공합니다.

  3. NS. 테스트 주도 개발을 할 때 중요합니다. IoC가 없으면 테스트 중인 구성 요소가 나머지 시스템과 밀접하게 결합되어 있으므로 테스트하기 어려울 수 있습니다.
    NS. 모듈식 시스템을 개발할 때 중요합니다. 모듈식 시스템은 재컴파일 없이 구성 요소를 교체할 수 있는 시스템입니다.
    씨. 부분적으로는 엔터프라이즈 애플리케이션에서 해결해야 하는 교차 문제가 많은 경우 중요합니다.


Glenn Block

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

 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) 컨테이너의 역전:
이것은 프레임워크의 일반적인 특성이며 IOC 는 Java 객체를 관리합니다.
– BeanFactory를 통한 인스턴스화에서 파괴까지.
- IoC 컨테이너에 의해 인스턴스화되는 Java 구성 요소를 빈이라고 하며 IoC 컨테이너는 빈의 범위, 수명 주기 이벤트 및 구성 및 코딩된 모든 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)을 구현함으로써 소프트웨어/객체 소비자는 통제를 받거나 더 적은 옵션을 갖는 대신 소프트웨어/객체에 대해 더 많은 제어/옵션을 얻습니다.

설계 지침으로서의 제어 역전은 다음과 같은 목적을 수행합니다.

구현에서 특정 작업의 실행이 분리됩니다.
모든 모듈은 설계된 목적에 집중할 수 있습니다.
모듈은 다른 시스템이 수행하는 작업에 대해 가정하지 않고 해당 계약에 의존합니다.
모듈을 교체해도 다른 모듈에는 부작용이 없습니다.
나는 여기에서 추상적인 것을 유지할 것입니다. 주제에 대한 자세한 이해를 위해 다음 링크를 방문할 수 있습니다.
예제와 함께 잘 읽었습니다

상해


VeKe

우리가 어떤 호텔에서 회의를 한다고 가정해 봅시다.

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

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

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

제어를 반전시키십시오.

같은 장소에서 같은 모임, 하지만 플라스틱 컵 대신에 우리는 웨이터가 하나의 유리 컵을 가지고 있습니다(Singleton)

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

누군가가 술을 마시고 싶을 때, 그녀는 웨이터 잔에서 가져와 마신 다음 웨이터에게 돌려줍니다.

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

그리고 이것이 바로 Spring(예: Guice)이 하는 또 다른 IoC 컨테이너입니다. 애플리케이션이 새로운 키워드를 사용하여 필요한 것을 생성하게 하는 대신(플라스틱 컵을 가져옴), 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 }

유용한 링크:-


Jainendra

NilObject에 동의하지만 여기에 추가하고 싶습니다.

전체 메서드를 복사하고 코드의 작은 부분만 변경하는 경우 제어 역전으로 문제를 해결할 수 있습니다.

코드를 복사하여 붙여넣는 경우 거의 항상 잘못된 작업을 수행하고 있는 것입니다. 설계 원칙으로 성문화 한 번만 .


Peter Burns

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

간단히 말해서 Control은 프로그래머에서 컨테이너로 반전됩니다. 그래서 역전(inversion of control)이라고 합니다.

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


gogs

여기 에서 '제어가 거꾸로 된' 방법을 설명하는 매우 명확한 예를 찾았습니다.

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

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

  • 응용 프로그램에는 Foo(예: 컨트롤러)가 필요하므로 다음을 수행합니다.
  • 응용 프로그램이 Foo를 만듭니다.
  • 애플리케이션 호출 Foo
    • Foo에는 Bar(예: 서비스)가 필요하므로:
    • Foo는 Bar를 생성합니다.
    • 푸가 바를 부른다
      • Bar에는 Bim(서비스, 리포지토리 등)이 필요하므로 다음을 수행합니다.
      • 바가 Bim을 만듭니다.
      • 바가 뭔가를 한다

의존성 주입 사용

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

  • 응용 프로그램에는 Foo가 필요하고 Bar가 필요하고 Bim이 필요하므로 다음을 수행합니다.
  • 애플리케이션에서 Bim 생성
  • 애플리케이션이 Bar를 생성하고 Bim을 제공합니다.
  • 응용 프로그램은 Foo를 생성하고 Bar를 제공합니다.
  • 애플리케이션 호출 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를 준수하는 한 컨트롤러를 변경할 필요가 없습니다.

테스트하는 동안 모든 메서드가 null(또는 테스트 요구 사항에 따라 미리 정의된 값)을 반환하는 더미 구현을 사용하여 StorageServiceInterface에 대한 모의를 만들 수 있습니다.

new 키워드로 스토리지 객체를 구성하는 컨트롤러 클래스가 있는 경우:

 class SomeController { private $storage; function __construct() { $this->storage = new GoogleDriveService(); } public function myFunction () { return $this->storage->getFile($fileName); } }

Dropbox 구현으로 변경하려면 new GoogleDriveService 개체가 생성되는 모든 줄을 교체하고 DropboxService를 사용해야 합니다. 게다가 SomeController 클래스를 테스트할 때 생성자는 항상 GoogleDriveService 클래스를 예상하고 이 클래스의 실제 메서드가 트리거됩니다.

언제가 적절하고 언제가 적절하지 않습니까? 제 생각에는 클래스의 대체 구현이 있다고 생각하거나 있을 수 있다고 생각할 때 DI를 사용합니다.


Raghavendra N

"IoC"의 두문자어와 이것이 의미하는 이름에 대해 가장 혼란스러운 점은 이름이 너무 화려해서 거의 시끄러운 이름인 것 같습니다.

절차적 프로그래밍과 이벤트 기반 프로그래밍의 차이점을 설명하는 이름이 정말로 필요한가요? 알겠습니다. 필요하다면 해결하는 것보다 더 혼란스러운 완전히 새로운 "생명보다 큰" 이름을 선택해야 합니까?


email.privacy

통제 역전은 당신이 식료품점에 갔을 때 당신의 아내가 당신에게 살 제품 목록을 줄 때입니다.

프로그래밍 용어로 그녀는 콜백 함수 getProductList() 를 실행 중인 함수인 doShopping() .

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


Sergiy Ostrovsky

여기에 이미 답이 있음을 이해합니다. 그러나 나는 여전히 미래의 독자를 위해 제어 역전(inversion of control)에 대한 몇 가지 기본 사항을 여기에서 길게 논의해야 한다고 생각합니다.

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

전화하지마세요 전화드리겠습니다

그것이 의미하는 바는 당신의 꿈을 이루기 위해 헐리우드에 가지 말고 당신이 가치가 있다면 헐리우드가 당신을 찾아 당신의 꿈을 이뤄줄 것이라는 것입니다. 꽤 거꾸로, 응?

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

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

실생활의 예가 여기에 주어질 것입니다. 웹 애플리케이션을 개발한다고 가정해 보겠습니다. 따라서 http 요청 처리, 애플리케이션 메뉴 생성, 페이지 제공, 쿠키 관리, 이벤트 트리거 등과 같이 웹 애플리케이션이 처리해야 하는 모든 일반적인 작업을 처리하는 프레임워크를 만듭니다.

그리고 나서 사용자 정의 메뉴, 페이지, 쿠키를 생성하거나 일부 사용자 이벤트 등을 기록하기 위해 추가 코드를 넣을 수 있는 프레임워크에 일부 후크를 남겨둡니다. 모든 브라우저 요청에서 프레임워크는 후크된 경우 사용자 정의 코드를 실행하고 실행한 다음 다시 제공합니다. 브라우저에.

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

Laravel과 EJB는 그러한 프레임워크의 예입니다.

참조:

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

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


Abdullah Al Farooq

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

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

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

확인된 것은 다음 관계입니다.

제어 역전(메소드용) = 종속성(상태) 주입 + 연속 주입 + 스레드 주입

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


Daniel Sagenschneider

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

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

그것은 말한다 -

"사소하지 않은 응용 프로그램은 일부 비즈니스 논리를 수행하기 위해 서로 협력하는 둘 이상의 클래스로 구성됩니다. 전통적으로 각 개체는 협력하는 개체(해당 종속성)에 대한 자체 참조를 얻는 책임이 있습니다. DI를 적용할 때, 객체는 시스템의 각 객체를 조정하는 외부 엔티티에 의해 생성 시 종속성을 부여받습니다. 즉, 종속성이 객체에 주입됩니다."


agaase

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

  • 일반적인 s/w 개발에서는 main() 메소드를 작성하고 "library" 메소드를 호출합니다. 당신 이 통제하고 있습니다 :)
  • IoC에서 "프레임워크"는 main()을 제어하고 메서드를 호출합니다. 프레임워크 가 제어 중입니다 :(

DI(Dependency Injection)는 애플리케이션에서 제어가 어떻게 흐를 것인가에 대한 것입니다. 기존 데스크톱 응용 프로그램에는 응용 프로그램(main() 메서드)에서 다른 라이브러리 메서드 호출로의 제어 흐름이 있었지만 DI 제어 흐름을 사용하면 프레임워크가 앱 시작, 초기화 및 필요할 때마다 메서드 호출을 처리하는 반전됩니다.

결국 당신은 항상 승리합니다 :)


Khanh

나는 이 설명을 좋아한다: 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가 그것을 모른다는 것입니다. I를 구현하는 것을 사용한다는 것을 알고 있습니다.

다음과 같은 혜택에 대한 추가 정보 및 설명을 보려면 기사를 읽으십시오.

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

...


DDan

프로그래밍 말하기

쉬운 용어로 IoC: 인터페이스를 일부 클래스에서 사용할 수 있는 와일드카드로 특정 항목(예: 필드 또는 매개변수)의 방법으로 사용하는 것입니다. 코드의 재사용성을 허용합니다.

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

그러나 실용적으로 말하면 약간의 역효과가 있습니다.

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

b) 몇 가지 제한 사항이 있습니다. 예를 들어 DogCat 의 경우에 대해 이야기하고 개만을 위한 새로운 서비스(기능)를 추가하고 싶습니다. 개를 훈련시켜야 하는 일수를 계산하고 싶다고 가정해 봅시다( trainDays() ). 고양이에게는 쓸모가 없고 고양이는 훈련할 수 없습니다(농담입니다).

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

b.2) 어떤 클래스가 사용되는지 평가 trainDays() 에 추가할 수 있습니다. 그러나 그것은 IoC를 완전히 깨뜨릴 것입니다.

b.3) 새로운 기능에 대해서만 DogService 라는 새로운 서비스 클래스를 만들 수 있습니다. 그러나 Dog에 대한 두 가지 서비스 클래스(유사한 기능 포함)가 있기 때문에 코드의 유지 관리 가능성이 높아집니다.


magallanes

제어 역전은 라이브러리에서 클라이언트로 제어를 전송하는 것입니다. 라이브러리 함수의 동작을 제어(변경)하는 고차 함수(라이브러리 함수)에 함수 값(람다 식)을 주입(전달)하는 클라이언트에 대해 이야기할 때 더 의미가 있습니다.

따라서 이 패턴의 간단한 구현(큰 의미 포함)은 고차 라이브러리 함수(다른 함수를 인수로 허용)입니다.

예를 들어 "map", "flatMap"과 같은 라이브러리 기능은 IoC 구현입니다.

라이브러리 종속성(동작을 전달하는)을 라이브러리에 주입하는 클라이언트 또는 프레임워크도 IoC로 간주될 수 있습니다.


Sergiu Starciuc

질문에 대한 답변은 이미 많이 있지만 그 중 어느 것도 Inversion Control 용어의 분석을 보여주지 않기 때문에 보다 간결하고 유용한 답변을 제공할 수 있는 기회가 있습니다.

제어 역전은 DIP(Dependency Inversion Principle)를 구현하는 패턴입니다. DIP는 다음을 명시합니다. 1. 상위 수준 모듈은 하위 수준 모듈에 의존해서는 안 됩니다. 둘 다 추상화(예: 인터페이스)에 의존해야 합니다. 2. 추상화는 세부 사항에 의존해서는 안됩니다. 세부사항(구체적인 구현)은 추상화에 의존해야 합니다.

제어 역전에는 세 가지 유형이 있습니다.

Interface Inversion Providers는 인터페이스를 정의해서는 안됩니다. 대신 소비자는 인터페이스를 정의해야 하고 공급자는 이를 구현해야 합니다. Interface Inversion을 사용하면 새 공급자가 추가될 때마다 소비자를 수정할 필요가 없습니다.

흐름 반전 흐름 제어를 변경합니다. 예를 들어, 많은 매개변수를 입력하도록 요청한 콘솔 응용 프로그램이 있고 각 매개변수를 입력한 후 강제로 Enter 키를 누릅니다. 여기에서 Flow Inversion을 적용하고 사용자가 매개변수 입력 순서를 선택할 수 있고 사용자가 매개변수를 편집할 수 있고 마지막 단계에서 사용자가 Enter 키를 한 번만 누르면 되는 데스크톱 응용 프로그램을 구현할 수 있습니다.

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


V. S.

나는 이것에 대한 많은 답변을 읽었지만 누군가가 여전히 혼란스럽고 IoC를 설명하기 위해 플러스 울트라 "평신도 용어"가 필요한 경우 여기에 내 의견이 있습니다.

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

IoC 없이:

*부모님 : 제가 질문할 때만 말을 할 수 있고, 제가 허락할 때만 행동할 수 있습니다.

부모 : 즉, 내가 묻지 않으면 먹고, 놀고, 화장실에 갈 수 있는지, 심지어 잠을 잘 수 있는지 물어볼 수 없습니다.

부모 : 먹을래?

아이 : 아니.

부모 : 알았어, 내가 돌아올게. 날 기다려.

아이 : (놀고 싶지만 부모의 질문이 없어서 아이가 할 수 있는 게 없어요.)

1 시간 후에...

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

아이 : 네.

부모 : 권한이 부여되었습니다.

아이 : (드디어 놀 수 있게 됨).

이 간단한 시나리오에서는 컨트롤이 부모 중심에 있음을 설명합니다. 아동의 자유는 제한되며 부모의 질문에 크게 의존합니다. 아이는 말하도록 요청받을 때만 말할 수 있고, 허락을 받았을 때만 행동할 수 있습니다.

IoC 사용:

이제 자녀는 질문할 수 있고 부모는 답변과 권한으로 응답할 수 있습니다. 단순히 컨트롤이 반전되었음을 의미합니다! 이제 아이는 언제든지 자유롭게 질문할 수 있으며 권한과 관련하여 여전히 부모에게 의존하지만 말하기/질문하는 수단에 의존하지 않습니다.

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


cattarantadoughan

IoC를 사용하면 개체를 새로 만들지 않습니다. IoC 컨테이너가 이를 수행하고 수명을 관리합니다.

한 유형의 객체를 다른 유형으로 인스턴스화할 때마다 수동으로 변경해야 하는 문제를 해결합니다.

향후 변경될 수 있거나 사용되는 환경이나 구성에 따라 다를 수 있는 기능이 있는 경우에 적합합니다.


Rush Frisby

개념을 이해하기 위해 IoC(Inversion of Control) 또는 DIP(Dependency Inversion Principle)에는 추상화와 반전이라는 두 가지 활동이 포함됩니다. DI(Dependency Injection)는 몇 가지 반전 방법 중 하나일 뿐입니다.

이에 대한 자세한 내용을 보려면 여기에서 내 블로그를 읽을 수 있습니다.

  1. 그것은 무엇입니까?

실제 동작이 경계 외부에서 발생하도록 하는 관행입니다(객체 지향 프로그래밍의 클래스). 경계 엔티티는 그것의 추상화(예: 인터페이스, 추상 클래스, 객체 지향 프로그래밍의 대리자)만 알고 있습니다.

  1. 어떤 문제를 해결합니까?

프로그래밍 측면에서 IoC는 모놀리식 코드를 모듈화하고 다양한 부분을 분리하고 단위 테스트 가능하게 만들어서 해결하려고 합니다.

  1. 언제가 적절하고 언제가 적절하지 않습니까?

모놀리식 코드(예: 매우 간단한 프로그램)만 원하는 상황이 아닌 한 대부분의 경우 적합합니다.


kusnaditjung tjung

출처 : http:www.stackoverflow.com/questions/3058/what-is-inversion-of-control

반응형