[inversion-of-control] Inversion of Control이란 무엇입니까?



14 Answers

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

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

기본적으로 이벤트 루프, 콜백 또는 실행 트리거가있는 모든 항목이이 범주에 속합니다.

Question

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

  1. 이게 뭐야?
  2. 어떤 문제가 해결됩니까?
  3. 적절한시기와 그렇지 않은 경우는 언제입니까?



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

장점 :

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

단점 :

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

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




Using IoC you are not new'ing up your objects. Your IoC container will do that and manage the lifetime of them.

It solves the problem of having to manually change every instantiation of one type of object to another.

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




IoC는 코드와 제 3 자 코드 (라이브러리 / 프레임 워크) 간의 관계를 바꾸는 것에 관한 것입니다.

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

DI (Dependency Injection)는 어플리케이션에서 컨트롤이 어떻게 움직이는 지에 대한 것입니다. 전통적인 데스크탑 애플리케이션은 애플리케이션 (main () 메소드)에서 다른 라이브러리 메소드 호출로의 제어 흐름을 가졌지 만, DI 제어 흐름은 반대로 프레임 워크가 앱을 시작하고, 초기화하고, 필요할 때마다 메소드를 호출합니다.

결국 당신은 항상 승리 :)




I like this explanation: http://joelabrahamsson.com/inversion-of-control-an-introduction-with-examples-in-net/

It start simple and shows code examples as well.

The consumer, X, needs the consumed class, Y, to accomplish something. That's all good and natural, but does X really need to know that it uses Y?

Isn't it enough that X knows that it uses something that has the behavior, the methods, properties etc, of Y without knowing who actually implements the behavior?

By extracting an abstract definition of the behavior used by X in Y, illustrated as I below, and letting the consumer X use an instance of that instead of Y it can continue to do what it does without having to know the specifics about Y.

In the illustration above Y implements I and X uses an instance of I. While it's quite possible that X still uses Y what's interesting is that X doesn't know that. It just knows that it uses something that implements I.

Read article for further info and description of benefits such as:

  • X is not dependent on Y anymore
  • More flexible, implementation can be decided in runtime
  • Isolation of code unit, easier testing

...




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

IoC없이 : 랩톱 컴퓨터를 가지고 실수로 화면이 깨집니다. 그리고, 당신은 동일한 모델의 노트북 화면이 시장 어디에도 없다는 것을 알게됩니다. 그래서 너는 붙어있다.

IoC 사용 : 데스크톱 컴퓨터가 있고 우연히 화면이 깨집니다. 시장에서 거의 모든 데스크탑 모니터를 가져올 수 있으며 데스크톱과도 잘 작동합니다.

이 경우 데스크톱이 IoC를 성공적으로 구현합니다. 다양한 종류의 모니터를 사용할 수 있지만 노트북은 그렇지 않습니다. 고정 스크린을 사용해야합니다.




"IoC"에 대한 가장 혼란스러운 점은 그것이 약자라는 이름이 너무 매력적이라는 것입니다.

절차 적 프로그래밍과 이벤트 구동 프로그래밍의 차이점을 설명하는 데 정말로 이름이 필요합니까? 우리가 필요하다면,하지만 해결할 것보다 더 혼란스러운 새로운 "삶보다 더 큰"이름을 고를 필요가 있습니까?




나는이 두 용어에 대한 나의 간단한 이해를 적어 둘 것이다.

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)

Inversion of Control (IoC) 컨테이너 :
이것은 프레임 워크의 일반적인 특성이며, IOC 는 자바 객체를 관리합니다.
- 인스턴스화에서 BeanFactory를 통한 파기.
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 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을 구현함으로써 소프트웨어 / 객체 소비자는 제어되거나 옵션이 적게 드는 대신 소프트웨어 / 객체에 대한 더 많은 제어 / 옵션을 얻습니다.

설계 가이드 라인으로서의 제어 반전은 다음과 같은 목적을 위해 사용됩니다.

특정 작업의 실행을 구현과 분리하는 방법이 있습니다.
모든 모듈은 자신이 의도 한 것에 집중할 수 있습니다.
모듈은 다른 시스템이하는 일에 대한 가정을하지 않고 계약에 의존합니다.
모듈 교체는 다른 모듈에 부작용이 없습니다.
나는 여기에 추상적 인 것들을 유지할 것이다. 당신은 주제에 대한 세부적인 이해를 위해 다음의 링크를 방문 할 수있다.
보기 좋은 예

상해




Creating an object within class is called tight coupling, Spring removes this dependency by following a design pattern(DI/IOC). In which object of class in passed in constructor rather than creating in class. More over we give super class reference variable in constructor to define more general structure.




우리가 어떤 호텔에서 어떤 만남을 가졌다 고하자.

많은 사람들, 물이 많은 카페인, 많은 플라스틱 컵.

누군가 마실 때 컵을 채우고 마시고 바닥에 컵을 던지십시오.

시간이 지나면 우리는 플라스틱 컵과 물로 바닥을 덮습니다.

반전 제어하자.

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

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

누군가 마실 것을 원하면 웨이터 글래스에서 음료를 마시고 웨이터에게 돌려 보내십시오.

위생의 문제를 떠나서 마시는 과정 통제의 마지막 형태는 훨씬 더 효과적이고 경제적입니다.

그리고 이것이 바로 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

}

유용한 링크:-




I found a very clear example here which explains how the 'control is inverted'.

Classic code (without Dependency injection)

Here is how a code not using DI will roughly work:

  • Application needs Foo (eg a controller), so:
  • Application creates Foo
  • Application calls Foo
    • Foo needs Bar (eg a service), so:
    • Foo creates Bar
    • Foo calls Bar
      • Bar needs Bim (a service, a repository, …), so:
      • Bar creates Bim
      • Bar does something

Using dependency injection

Here is how a code using DI will roughly work:

  • Application needs Foo, which needs Bar, which needs Bim, so:
  • Application creates Bim
  • Application creates Bar and gives it Bim
  • Application creates Foo and gives it Bar
  • Application calls Foo
    • Foo calls Bar
      • Bar does something

The control of the dependencies is inverted from one being called to the one calling.

What problems does it solve?

Dependency injection makes it easy to swap with the different implementation of the injected classes. While unit testing you can inject a dummy implementation, which makes the testing a lot easier.

Ex: Suppose your application stores the user uploaded file in the Google Drive, with DI your controller code may look like this:

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) {}
}

When your requirements change say, instead of GoogleDrive you are asked to use the Dropbox. You only need to write a dropbox implementation for the StorageServiceInterface. You don't have make any changes in the controller as long as Dropbox implementation adheres to the StorageServiceInterface.

While testing you can create the mock for the StorageServiceInterface with the dummy implementation where all the methods return null(or any predefined value as per your testing requirement).

Instead if you had the controller class to construct the storage object with the new keyword like this:

class SomeController
{
    private $storage;

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

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

When you want to change with the Dropbox implementation you have to replace all the lines where new GoogleDriveService object is constructed and use the DropboxService. Besides when testing the SomeController class the constructor always expects the GoogleDriveService class and the actual methods of this class are triggered.

When is it appropriate and when not? In my opinion you use DI when you think there are (or there can be) alternative implementations of a class.




말하기 프로그래밍

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

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

그러나, 실용적인 말로하면, 그것은 거꾸로있다.

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

b) 제한이있다. 예를 들어 Dog and Cat 의 사례에 대해 이야기하고 만을위한 새로운 서비스 (기능)를 추가하겠습니다. 개를 훈련 시키는데 필요한 일수를 계산하기를 원한다고 가정 해 봅시다. 고양이에게는 쓸모가 없으며 고양이는 훈련을받을 수 없습니다 (농담입니다).

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

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

b.3) 새로운 기능을 위해서 DogService 라는 새로운 서비스 클래스를 만들 수 있습니다. 그러나 Dog 의 경우 두 클래스의 서비스 (유사한 기능 포함)를 사용하게되므로 코드 유지 관리가 향상됩니다.




하지만 당신이 그걸 아주 조심해야한다고 생각합니다. 이 패턴을 과도하게 사용하면 매우 복잡한 디자인과 더욱 복잡한 코드를 작성하게됩니다.

이 예제에서 TextEditor와 같이 : SpellChecker가 하나만있는 경우라면 IoC를 사용할 필요가 없을 수도 있습니다. 단위 테스트 나 뭔가를 쓸 필요가 없다면 ...

어쨌든 : 합리적이어야합니다. 디자인 패턴은 훌륭한 관행 이지만 설교 할 성서는 아닙니다. 어디서나 붙이지 마십시오.




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

IoC가 없으면 : "사과"를 요구하고, 더 많이 물을 때 항상 사과를 먹습니다.

IoC : "과일"을 요구할 수 있습니다. 당신은 봉사 할 때마다 다른 과일을 얻을 수 있습니다. 예 : 사과, 오렌지 또는 수박.

그래서 IoC가 다양성을 좋아할 때 선호됩니다.




IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes, or a mechanism such as the Service Locator pattern

Spring-framework-referance.pfd page 27 (if counting all pdf document pages, it is in page 51)

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/pdf/spring-framework-reference.pdf




Related