제어의 반전 대 의존성 주입


525

Martin Fowler가 작성한 논문 에 따르면 제어의 반전은 프로그램의 제어 흐름이 반전되는 원리입니다. 프로그래머가 프로그램의 흐름을 제어하는 ​​대신 외부 소스 (프레임 워크, 서비스, 기타 구성 요소)가 그것. 마치 무언가를 다른 것에 연결하는 것과 같습니다. 그는 EJB 2.0에 대한 예를 언급했습니다.

예를 들어 Session Bean 인터페이스는 ejbRemove, ejbPassivate (보조 스토리지에 저장 됨) 및 ejbActivate (패시브 상태에서 복원 됨)를 정의합니다. 이러한 메소드가 호출되는 시점을 제어 할 수 없으며 수행 방식 만 수행 할 수 있습니다. 컨테이너는 우리를 부르고 우리는 부르지 않습니다.

이는 프레임 워크와 라이브러리의 차이점으로 이어집니다.

제어의 반전은 프레임 워크를 라이브러리와 다르게 만드는 주요 부분입니다. 라이브러리는 본질적으로 호출 할 수있는 함수 세트이며, 요즘에는 대개 클래스로 구성됩니다. 각 호출은 일부 작업을 수행하고 클라이언트에게 제어권을 반환합니다.

DI가 IOC라는 관점은 객체의 종속성이 반전된다는 것을 의미합니다. 자체 종속성, 수명주기를 제어하는 ​​대신 다른 무언가가 당신을 위해 그것을합니다. 그러나 DI에 대해 직접 말했듯이 DI는 반드시 IOC 일 필요는 없습니다. 우리는 여전히 DI와 IOC를 가질 수 없습니다.

그러나이 백서 (C / C ++의 또 다른 IOC 프레임 워크 인 pococapsule에서)는 IOC와 DI 때문에 I2 컨테이너와 DI 프레임 워크가 J2EE보다 훨씬 우수하다는 것을 제안합니다. 따라서 POJO / POCO (Plain Old Java / C ++ Object)로 만들지 않습니다.

종속성 주입 패턴 이외의 제어 컨테이너 반전 (아카이브 링크)

이전의 컴포넌트 기반 개발 프레임 워크의 문제점을 이해하기위한 추가 자료, 위의 두 번째 논문 : 제어의 반전 이유 및 이유 (아카이브 링크)

내 질문 : IOC와 DI는 정확히 무엇입니까? 혼란 스러워요. pococapsule을 기반으로 IOC는 객체 또는 프로그래머와 프레임 워크 간의 제어를 뒤집는 것보다 더 중요한 것입니다.


2
다음은 주제에 대한 좋은 글입니다 .IoC vs DI (Dependency Inject) vs SL (Service Locator) : tinyurl.com/kk4be58-URL 에서 추출 : IoC vs DI (Dependency Injection)? IoC는 흐름 제어가 클라이언트 코드에서 프레임 워크로 반전 되는 일반적인 개념으로 , "클라이언트를 위해 무언가를합니다". SL (Service Locator) 및 DI (Dependency Injection)는 IoC에서 파생 된 두 가지 디자인 패턴입니다.
Swa.Jat

의존성 주입이 커피 숍 테마에 도움이 될 수있는 방법에 관심이 있다면, 2 센트를 추가하기 위해 digigene.com/design-patterns/dependency-injection-coffeeshop
Ali Nem


의존성 역전 : concretion이 아닌 추상화에 의존합니다. 제어 역전 : 메인 대 추상화, 메인이 시스템의 접착제 인 방법. 이것에 대해 좋은 소식이 있습니다 : coderstower.com/2019/03/26/… coderstower.com/2019/04/02/… coderstower.com/2019/04/09/…
Daniel Andres Pelaez Lopez

이 깊이에 대해 읽으면 모든 martinfowler.com/articles/…
Dushman

답변:


644

IoC 는 애플리케이션이 프레임 워크에서 메소드를 호출하는 것이 아니라 일반적인 용어의 의미이며, 프레임 워크는 애플리케이션이 제공하는 구현을 호출합니다.

DI 는 IoC의 한 형태로, 구현은 생성자 / 설정자 / 서비스 조회를 통해 객체로 전달되며, 객체는 올바르게 동작하기 위해 '종속'됩니다.

DI를 사용하지 않는 IoC 는 구현이 서브 클래 싱을 통해서만 변경 될 수 있기 때문에 템플릿 패턴이됩니다.

DI 프레임 워크DI 를 사용하도록 설계되었으며 구현에 쉽게 전달할 수 있도록 인터페이스 (또는 Java의 주석)를 정의 할 수 있습니다.

IoC 컨테이너 는 프로그래밍 언어 외부에서 작동 할 수있는 DI 프레임 워크입니다. 일부는 덜 침입적인 메타 데이터 파일 (예 : XML)에 사용할 구현을 구성 할 수 있습니다. 일부에서는 pointcuts에 구현을 주입하는 것과 같이 일반적으로 불가능한 IoC를 수행 할 수 있습니다 .

Martin Fowler의 기사도 참조하십시오 .


2
답변 해주셔서 감사합니다. 그러나 다른 논문에서는 IOC를 사용하면 IOC 컨테이너가 EJB보다 훨씬 뛰어나다는 것을 제안하지만 Martin Fowler는 EJB가 IOC의 전형적인 예라고 제안합니다.
Amumu

5
EJB 관리는 실제로 IoC의 전형적인 예입니다. EJB의 수명주기는 프로그래머가 아닌 컨테이너가 관리한다는 사실에서 볼 수 있습니다. 제어권이 서버에 위임 되었으므로 프로그래머는 EJB 인스턴스를 작성하거나 삭제하지 않습니다 . 이것이 바로 IoC의 개념입니다 : 외부 코드는 코드가 호출 될 때를 제어하는데, 이는 대개 대부분의 시간 과 반대 입니다.
brandizzi

2
IoC는 애플리케이션이 프레임 워크에서 메소드를 호출하는 것이 아니라 일반적인 용어의 의미이며, 프레임 워크는 애플리케이션이 제공하는 구현을 호출합니다. 이것에 대해 더 자세히 설명해 주시겠습니까?
Imad Alazani

21
일명 할리우드 원칙 , '전화하지 마십시오. 전화하겠습니다.' 응용 프로그램이 아닌 프레임 워크에 대한 호출을 남겨 둡니다.
개럿 홀

@ImadAlazani, 개럿이 첨부 한 기사를 읽는 것이 좋을 것이다. 이것은 애플리케이션 코드에서 프레임 워크로 컨트롤을 뒤집는 것에 대한 자세한 논의이다.
MengT

210

요컨대, IoC는 DI를 포함하지만 이에 국한되지 않는 훨씬 광범위한 용어입니다.

IoC (Inversion of Control)라는 용어는 원래 전체 프레임 워크 또는 런타임이 프로그램 흐름을 제어하는 ​​모든 종류의 프로그래밍 스타일을 의미했습니다.

DI가 이름을 갖기 전에 사람들은 종속성을 제어 컨테이너의 반전으로 관리하는 프레임 워크를 참조하기 시작했으며 곧 IoC의 의미가 점차 특정 의미 인 종속성에 대한 제어의 반전으로 바뀌 었습니다.

IoC ( Inversion of Control )는 개체가 작업에 의존하는 다른 개체를 만들지 않음을 의미합니다. 대신 외부 소스 (예 : xml 구성 파일)에서 필요한 객체를 가져옵니다.

DI ( Dependency Injection )는 일반적으로 생성자 매개 변수를 전달하고 속성을 설정하는 프레임 워크 구성 요소에 의해 개체 개입없이 수행됩니다.


1
IoC가 Depency Inversion 원칙의 또 다른 용어 인 것 같습니다.
토드 밴스

@ToddVance-예, IoC와 DIP가 같은 것 같습니다. DIP와 DI는 같은 것이 아닙니다. DI없이 IoC를 수행 할 수 있지만 IoC없이 DI를 수행 할 수 없습니다.
Eljay

2
@ToddVance-아니요, DIP 및 IoC는 동의어가 아니며 관련이 없습니다.
TSmith

3
하, 그것이
Todd Vance

50

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

IoC ( I nversion o f C ontrol) :-일반적인 용어이며 여러 가지 방법 (이벤트, 델리게이트 등)으로 구현됩니다.

DI ( D ependency I njection) - DI는 IOC는의 서브 타입에 의해 구현되는 생성자 주입 세터 주사 또는 주입 인터페이스 .

그러나 Spring은 다음 두 가지 유형 만 지원합니다.

  • 세터 주입
    • Setter 기반 DI는 인수 없음 생성자 또는 인수 없음 정적 팩토리 메소드를 호출하여 Bean을 인스턴스화 한 후 사용자 Bean에서 setter 메소드를 호출하여 실현됩니다.
  • 생성자 주입
    • 생성자 기반 DI는 각각 공동 작업자를 나타내는 여러 인수로 생성자를 호출하여 구현됩니다.이를 사용하여 삽입 된 Bean이 널이 아니고 빠르게 실패하는지 (컴파일 시간에 실패하고 런타임에 실패) 유효성을 검증 할 수 있습니다. 응용 프로그램 자체를 시작하는 동안 우리는 얻을 수 NullPointerException: bean does not exist있습니다. 생성자 주입은 종속성을 주입하는 가장 좋은 방법입니다.

1
스프링이 속성 주입을 지원하지 않는다는 것은 올바르지 않습니다. 그렇습니다. 그리고 그것은 나쁜 습관입니다, 동의합니다.
kekko12

봄 @Autowired 주석은 내 의견으로는 재산 주입의 방법입니다
Sajith

49

DI는 IoC의 하위 집합입니다

  • IoC 는 객체가 자신의 작업에 의존하는 다른 객체를 생성하지 않음을 의미합니다. 대신 외부 서비스 (예 : xml 파일 또는 단일 앱 서비스)에서 필요한 개체를 가져옵니다. 내가 사용하는 IoC의 두 가지 구현은 DI와 ServiceLocator입니다.
  • DI 는 구체적인 객체를 사용하지 않고 추상화 (인터페이스)를 사용하지 않고 종속 객체를 얻는 IoC 원칙을 의미합니다. 이렇게하면 모든 구성 요소 체인을 테스트 할 수 있으며, 상위 구성 요소는 하위 수준 구성 요소에 의존하지 않고 인터페이스에서만 가능합니다. Mocks는 이러한 인터페이스를 구현합니다.

다음은 IoC를 달성하기위한 다른 기술들 입니다.


IoC가 객체를 만들지 않는다는 의미는 아닙니다. 클래스 메소드를 직접 호출하지 않고 인터페이스 메소드를 호출하면 제어의 반전 (이 경우 호출자는 호출 코드에 의존하지 않음)이며 객체 생성과 전혀 관련이 없습니다. IoC의 또 다른 예는 이벤트 및 대표자입니다.
Eugene Gorbovoy

19

모든 대답이 이론을 강조하기 때문에 첫 번째 접근법의 예를 보여 드리겠습니다.

주문이 배송되면 SMS 확인 메시지를 보내는 기능이 포함 된 응용 프로그램을 구축한다고 가정합니다. 우리는 두 가지 클래스를 가질 것입니다. 하나는 SMS (SMSService)를 전송하고 다른 하나는 사용자 입력 (UIHandler)을 캡처해야합니다. 코드는 다음과 같습니다.

public class SMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
    }
}

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        SMSService _SMSService = new SMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

위의 구현은 잘못된 것이 아니지만 몇 가지 문제가 있습니다
.-) 개발 환경에서 SMS 게이트웨이를 사용하는 대신 텍스트 파일로 전송 된 SMS를 저장하여이를 달성하려고합니다. 다른 구현으로 (SMSService)의 구체적인 구현을 변경하면 유연성이 떨어지고이 경우 코드를 다시 작성해야합니다.
-) 클래스의 혼합 책임을 끝내고, (UIHandler)는 (SMSService)의 구체적인 구현에 대해 절대 알 수 없어야합니다. 이는 "인터페이스"를 사용하여 클래스 외부에서 수행해야합니다. 이것이 구현되면 동일한 인터페이스를 구현하는 다른 모의 서비스와 함께 사용되는 (SMSService)를 교체하여 시스템의 동작을 변경할 수 있습니다.이 서비스는 mobileNumber로 전송하는 대신 SMS를 텍스트 파일로 저장합니다.

위의 문제를 해결하기 위해 우리는 우리의 (SMSService) 및 새로운 (MockSMSService)에 의해 구현되는 인터페이스를 사용합니다. 기본적으로 새로운 인터페이스 (ISMSService)는 아래 코드와 동일한 서비스 동작을 노출합니다.

public interface ISMSService
{
    void SendSMS(string phoneNumber, string body);
}

그런 다음 (SMSService) 인터페이스를 구현하기 위해 (SMSService) 구현을 변경합니다.

public class SMSService : ISMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
        Console.WriteLine("Sending SMS using gateway to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

이제 동일한 인터페이스를 사용하여 완전히 다른 구현으로 새로운 목업 서비스 (MockSMSService)를 만들 수 있습니다.

public class MockSMSService :ISMSService
{
    public void SendSMS(string phoneNumber, string body)
    {
        SaveSMSToFile(phoneNumber,body);
    }

    private void SaveSMSToFile(string mobileNumber, string body)
    {
        /*implementation for saving SMS to a file*/
        Console.WriteLine("Mocking SMS using file to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

이 시점에서 아래와 같이 (UIHandler)의 코드를 변경하여 구체적인 서비스 구현 (MockSMSService)을 쉽게 사용할 수 있습니다.

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        ISMSService _SMSService = new MockSMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

우리는 코드에서 많은 유연성을 달성하고 코드 분리 문제를 구현했지만 두 SMS 서비스 간을 전환하려면 코드베이스를 변경해야합니다. 따라서 Dependency Injection 을 구현해야합니다 .

이를 위해서는 (UIHandler) 클래스 생성자에 대한 변경 사항을 구현하여 종속성을 전달해야합니다. 이렇게하면 (UIHandler)를 사용하는 코드가 (ISMSService)의 구체적인 구현을 결정할 수 있습니다.

public class UIHandler
{
    private readonly ISMSService _SMSService;

    public UIHandler(ISMSService SMSService)
    {
        _SMSService = SMSService;
    }

    public void SendConfirmationMsg(string mobileNumber)
    {
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

이제 클래스 (UIHandler)와 통신 할 UI 양식은 사용할 인터페이스 구현 (ISMSService)을 전달해야합니다. 이것은 우리가 컨트롤을 뒤집 었음을 의미합니다. (UIHandler)는 더 이상 사용할 구현을 결정할 책임이 없으며 호출 코드는 수행합니다. DI가 그것의 한 유형 인 Inversion of Control 원리를 구현 했습니다.

UI 폼 코드는 다음과 같습니다.

class Program
{
    static void Main(string[] args)
    {
        ISMSService _SMSService = new MockSMSService(); // dependency

        UIHandler _UIHandler = new UIHandler(_SMSService);
        _UIHandler.SendConfirmationMsg("96279544480");

        Console.ReadLine();
    }
}

훌륭한 설명
ZiviMagic

19

IOC (Inversion Of Control) : 객체의 인스턴스를 얻기 위해 컨테이너에 제어 권한을 부여하는 것을 제어의 반전이라고합니다. 새로운 연산자를 사용하여 객체를 생성하는 대신 컨테이너가 자동으로 처리하도록하십시오.

DI (종속 주입) : 객체에 속성을 주입하는 방법을 의존성 주입 이라고 합니다.

의존성 주입 에는 세 가지 유형이 있습니다 .

  1. 생성자 주입
  2. 세터 / 게터 주입
  3. 인터페이스 주입

Spring은 Constructor InjectionSetter / Getter Injection 만 지원합니다 .



5

IoC- 제어의 반전은 언어와 무관 한 일반적인 용어로, 실제로 객체를 생성하는 것이 아니라 어떤 패션 객체를 생성하는지 설명합니다.

DI- 의존성 주입은 구체적인 주입 용어로, 다른 주입 기법을 사용하여 런타임에 객체의 의존성을 제공합니다. 세터 주입, 생성자 주입 또는 인터페이스 주입.


4

제어 역전은 응용 프로그램의 대상 구성 요소 (작업을 수행하는 구성 요소)에 더 많은 제어 기능을 제공한다는 목표를 가진 디자인 패러다임입니다.
의존성 주입은 컴파일 타임에 어떤 클래스가 해당 기능을 제공하는 데 사용 될지 모르면서 다른 객체가 의존하는 객체의 인스턴스를 만드는 데 사용되는 패턴입니다.

제어 역전을 구현하는 몇 가지 기본 기술이 있습니다. 이것들은:

  • 팩토리 패턴 사용
  • 서비스 로케이터 패턴 사용
  • 아래 유형의 의존성 주입 사용 :

    1). 생성자 주입
    2). 세터 주입
    3). 인터페이스 주입

4

DIIOC 는 주로 컴포넌트 간의 느슨한 결합 을 제공하는 데 중점을 두는 두 가지 디자인 패턴 이거나 단순히 오브젝트가 서로 밀접하게 연결되지 않도록 오브젝트 간의 기존 종속성 관계를 분리하는 방식입니다.

다음 예제를 통해 두 가지 개념을 모두 설명하려고합니다.

이전에는 이와 같은 코드를 작성하고 있습니다

Public MyClass{
 DependentClass dependentObject
 /*
  At somewhere in our code we need to instantiate 
  the object with new operator  inorder to use it or perform some method.
  */ 
  dependentObject= new DependentClass();
  dependentObject.someMethod();
}

의존성 주입을 사용하면 의존성 인젝터가 객체의 인스턴스화를 처리합니다.

Public MyClass{
 /* Dependency injector will instantiate object*/
 DependentClass dependentObject

 /*
  At somewhere in our code we perform some method. 
  The process of  instantiation will be handled by the dependency injector
 */ 

  dependentObject.someMethod();
}

인스턴스화 및 주입을 위해 제어를 다른 (예 : 컨테이너)에 제공하는 위의 프로세스를 제어의 반전이라고하고 IOC 컨테이너가 종속성을 주입하는 프로세스를 종속성 주입이라고합니다.

IOC는 프로그램의 제어 흐름이 역전되는 원리입니다. 프로그래머가 프로그램의 흐름을 제어하는 ​​대신 , 프로그램은 프로그래머 오버 헤드를 줄여 흐름을 제어합니다. DI

두 개념은 함께 작동하여 훨씬 유연하고 재사용 가능하며 캡슐화 된 코드를 작성하여 객체 지향 솔루션을 설계 할 때 중요한 개념으로 만듭니다.

또한 읽을 것을 권장합니다.

의존성 주입이란 무엇입니까?

비슷한 대답 중 하나를 여기서 확인할 수도 있습니다.

제어 역전 및 의존성 주입의 차이점


3

Inversion of Control은 유지 관리가 쉬운 재사용 가능한 모듈 식 소프트웨어 프레임 워크를 만드는 데 도움이되는 소프트웨어 아키텍처의 일반적인 설계 원칙입니다.

제어 흐름이 일반 작성 라이브러리 또는 재사용 가능한 코드에서 "수신"되는 설계 원칙입니다.

그것을 더 잘 이해하기 위해, 우리가 초기 코딩에서 코딩하는 방법을 보자. 절차 적 / 전통적 언어에서 비즈니스 로직은 일반적으로 응용 프로그램의 흐름을 제어하고 일반 또는 재사용 가능한 코드 / 기능을 "통화"합니다. 예를 들어 간단한 콘솔 응용 프로그램에서 제어 흐름은 프로그램의 지침에 의해 제어되며 여기에는 일반적인 재사용 가능한 함수에 대한 호출이 포함될 수 있습니다.

print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);

//More print and scan statements
<Do Something Interesting>

//Call a Library function to find the age (common code)
print Age

반대로 IoC와 함께 프레임 워크는 비즈니스 로직을 "호출"하는 재사용 가능한 코드입니다.

예를 들어, Windows 기반 시스템에서 버튼, 메뉴, 창 및 대화 상자와 같은 UI 요소를 작성하기위한 프레임 워크가 이미 사용 가능합니다. 애플리케이션의 비즈니스 로직을 작성할 때 비즈니스 로직 코드 (이벤트가 발생할 때)를 호출하는 프레임 워크의 이벤트가 될 것이며 반대는 아닙니다.

프레임 워크의 코드는 내 비즈니스 로직을 인식하지 못하지만 내 코드를 호출하는 방법을 여전히 알고 있습니다. 이것은 이벤트 / 위임, 콜백 등을 사용하여 달성됩니다. 여기서 흐름 제어는 "반전"입니다.

따라서 정적으로 바인딩 된 개체에 대한 제어 흐름에 의존하는 대신 흐름은 전체 개체 그래프와 다른 개체 간의 관계에 따라 다릅니다.

의존성 주입은 객체의 의존성을 해결하기위한 IoC 원칙을 구현하는 디자인 패턴입니다.

간단히 말해서, 코드를 작성하려고 할 때 다른 클래스를 작성하고 사용하게됩니다. 한 클래스 (클래스 A)는 다른 클래스 (클래스 B 및 / 또는 D)를 사용할 수 있습니다. 따라서 클래스 B와 D는 클래스 A의 종속성입니다.

간단한 비유는 클래스 카가 될 것입니다. 자동차는 엔진, 타이어 등과 같은 다른 클래스에 의존 할 수 있습니다.

의존성 주입은 의존성 (클래스 엔진 및 클래스 타이어)을 생성하는 의존성 클래스 (클래스 카) 대신 클래스가 의존성의 구체적인 인스턴스로 주입되어야한다고 제안합니다.

보다 실제적인 예를 통해 이해할 수 있습니다. 자신 만의 TextEditor를 작성한다고 가정하십시오. 무엇보다도 텍스트의 오타를 확인할 수있는 기능을 사용자에게 제공하는 맞춤법 검사기를 사용할 수 있습니다. 이러한 코드의 간단한 구현은 다음과 같습니다.

Class TextEditor
{

    //Lot of rocket science to create the Editor goes here

    EnglishSpellChecker objSpellCheck;
    String text;

    public void TextEditor()

    {   

        objSpellCheck = new EnglishSpellChecker();

    }

    public ArrayList <typos> CheckSpellings()
    {

        //return Typos;

    }

}

첫눈에, 모두 장미 빛 보인다. 사용자는 일부 텍스트를 작성합니다. 개발자는 텍스트를 캡처하고 CheckSpellings 함수를 호출하고 사용자에게 표시 할 오타 목록을 찾습니다.

한 명의 사용자가 편집자에서 프랑스어를 쓰기 시작하는 좋은 날까지 모든 것이 잘 작동하는 것 같습니다.

더 많은 언어를 지원하려면 더 많은 SpellChecker가 있어야합니다. 아마도 프랑스어, 독일어, 스페인어 등

여기서는 "English"SpellChecker가 TextEditor 클래스와 밀접하게 연결되어 밀접하게 결합 된 코드를 만들었습니다. 이는 TextEditor 클래스가 EnglishSpellChecker에 의존하거나 EnglishSpellCheker가 TextEditor에 대한 종속성임을 의미합니다. 이 의존성을 제거해야합니다. 또한 텍스트 편집기는 런타임시 개발자의 판단에 따라 맞춤법 검사기의 구체적인 참조를 유지할 수있는 방법이 필요합니다.

DI 소개에서 보았 듯이 클래스에는 종속성이 주입되어야합니다. 따라서 호출 된 클래스 / 코드에 모든 종속성을 주입하는 것은 호출 코드의 책임이어야합니다. 코드를 다음과 같이 재구성 할 수 있습니다.

interface ISpellChecker
{

    Arraylist<typos> CheckSpelling(string Text);

}

Class EnglishSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}



Class FrenchSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}

이 예에서 TextEditor 클래스는 ISpellChecker 형식의 구체적인 인스턴스를 받아야합니다.

이제 생성자, 공용 속성 또는 메서드에 종속성을 삽입 할 수 있습니다.

Constructor DI를 사용하여 클래스를 변경해 봅시다. 변경된 TextEditor 클래스는 다음과 같습니다.

Class TextEditor

{

    ISpellChecker objSpellChecker;

    string Text;



    public void TextEditor(ISpellChecker objSC)

    {

        objSpellChecker = objSC;

    }



    public ArrayList <typos> CheckSpellings()

    {

        return objSpellChecker.CheckSpelling();

    }

}

따라서 호출 코드가 텍스트 편집기를 작성하는 동안 적절한 SpellChecker 유형을 TextEditor 인스턴스에 삽입 할 수 있습니다.

여기 에서 전체 기사를 읽을 수 있습니다


3

IOC (Inversion Of Control) : 개체의 인스턴스를 얻기 위해 컨테이너에 제어 권한을 부여하는 것을 Inversion of Control이라고합니다. new operator를 사용하여 객체를 만드는 대신 컨테이너가 대신 하도록하십시오.

DI (Dependency Injection) : XML에서 POJO CLASS의 객체로 필요한 매개 변수 (속성)를 전달하는 것을 Dependency injection이라고합니다.


2

IOC 는 애플리케이션 클래스를 관리하는 외부 클래스를 나타내며 외부 클래스는 컨테이너가 애플리케이션 클래스 간의 종속성을 관리함을 의미합니다. IOC의 기본 개념은 프로그래머가 객체를 만들 필요는 없지만 객체를 만드는 방법을 설명한다는 것입니다.

IoC 컨테이너가 수행하는 주요 작업은 다음과 같습니다 . 응용 프로그램 클래스를 인스턴스화합니다. 개체를 구성합니다. 객체 사이의 의존성을 조립합니다.

DI 는 세터 주입 또는 생성자 주입을 사용하여 런타임시 오브젝트의 종속성을 제공하는 프로세스입니다.


2

IOC (Inversion of Control)는 기본적으로 종속성을 제거하고 흐름을 비선형으로 만들기 위해 연결을 분리하고 컨테이너 / 또는 다른 엔티티가 종속성의 프로비저닝을 관리하게하는 디자인 패턴 개념입니다. 실제로 할리우드 교장 인“전화하지 마십시오. 전화하겠습니다”를 따릅니다. 차이점을 요약합니다.

제어의 반전 :-의존성을 분리하고 프로비저닝을 위임하는 일반적인 용어이며 여러 가지 방법 (이벤트, 위임 등)으로 구현할 수 있습니다.

의존성 주입 :-DI는 IOC의 하위 유형이며 생성자 주입, 세터 주입 또는 메소드 주입으로 구현됩니다.

다음 기사는 이것을 매우 깔끔하게 설명합니다.

https://www.codeproject.com/Articles/592372/Dependency-Injection-DI-vs-Inversion-of-Control-IO


1

나는 아이디어가 혼란스러워 보이는 Object Oriented 잡초에 빠지지 않고도 그 아이디어를 명확하게 보여줄 수 있다고 생각합니다.

// dependency injection
function doSomething(dependency) {
    // do something with your dependency
}

// in contrast to creating your dependencies yourself
function doSomething() {
    dependency = getDependencySomehow()
}

// inversion of control
application = makeApp(authenticate, handleRequest, sendResponse)
application.run(getRequest())

// in contrast to direct control or a "library" style
application = makeApp()
request = application.getRequest()

if (application.authenticate(request.creds)) {
    response = application.handleRequest(request)
    application.sendResponse(response)
}

머리를 기울이고 눈을 가늘게 뜨면 DI가 특정 관심사를 가진 IoC의 특정 구현임을 알 수 있습니다. 모델과 동작을 응용 프로그램 프레임 워크 또는 상위 작업에 주입하는 대신 변수를 함수 또는 객체에 주입합니다.


0

SOLID의 D로 시작하여 Scott Millett의 저서 "Professional ASP.NET Design Patterns"에서 DI와 IoC를 살펴 보겠습니다.

의존성 역전 원리 (DIP)

DIP는 구체적인 구현에서 클래스를 분리하고이 추상 클래스 나 인터페이스에 따라 필요에 대한 모든 것입니다. 그것은 구현이 아닌 인터페이스에 대한 코딩의 진언을 촉진 시키며, 이는 하나의 구현에 밀접하게 연결되지 않도록하여 시스템 내에서 유연성을 증가시킵니다.

의존성 주입 (DI) 및 제어 역전 (IoC)

DI 원칙과 IoC 원칙은 DIP와 밀접하게 연결되어 있습니다. DI 는 생성자, 메서드 또는 속성을 통해 저수준 또는 종속 클래스를 제공하는 행위입니다. DI와 함께 사용되는 이러한 종속 클래스는 인터페이스 또는 추상 클래스로 전환되어 테스트가 쉽고 변경하기 쉬운 느슨하게 연결된 시스템으로 이어질 수 있습니다.

에서는 IOC는 , 제어 시스템의 흐름은 절차 형 프로그래밍에 비해 반전된다. 이에 대한 예는 IoC 컨테이너로 , 구체적인 구현을 지정하는 클라이언트 코드없이 클라이언트 코드에 서비스를 삽입하는 것이 목적입니다. 이 인스턴스에서 반전되는 제어는 클라이언트가 서비스를 얻는 행위입니다.

Millett, C (2010). 전문 ASP.NET 디자인 패턴. 와일리 출판. 7-8.


0

// ICO, DI, 10 년 전, 이것은 다음과 같습니다.

public class  AuditDAOImpl implements Audit{

    //dependency
    AuditDAO auditDAO = null;
        //Control of the AuditDAO is with AuditDAOImpl because its creating the object
    public AuditDAOImpl () {
        this.auditDAO = new AuditDAO ();
    }
}

이제 Spring 3,4 또는 최신 버전은 아래와 같습니다.

public class  AuditDAOImpl implements Audit{

    //dependency

     //Now control is shifted to Spring. Container find the object and provide it. 
    @Autowired
    AuditDAO auditDAO = null;

}

전반적으로 제어는 기존 개념의 결합 코드에서 Spring과 같은 프레임 워크로 반전되어 개체를 사용할 수있게합니다. 따라서 Constructor 또는 setters를 사용하여 종속 객체를 다른 객체에 주입 할 때 아는 한 IOC입니다. 주입은 기본적으로 인수로 전달하는 것을 의미합니다. 봄에는 빈 객체를 정의하고 생성자 또는 세터 주입 스타일로 종속 객체를 전달하는 XML 및 주석 기반 구성이 있습니다.


0

Dzone.com 에서 IOC와 DI의 실제 차이점을 이해하는 데 도움이 되는 가장 좋은 예를 찾았습니다.

"IoC는 다른 사람이 당신을 위해 객체를 만들 때입니다." 따라서 코드에 "new"키워드 (예 : MyCode c = new MyCode ())를 작성하는 대신 다른 사람이 객체를 만듭니다. 이 '다른 사람'은 일반적으로 IoC 컨테이너라고합니다. 그것은 우리가 객체의 인스턴스를 얻기 위해 컨테이너에 rrsponsibility (control)를 인버트하는 것을 컨트롤의 반전이라고합니다. 새로운 연산자를 사용하여 객체를 생성하는 대신 컨테이너가 대신하도록하십시오.

   DI(Dependency Injection):  Way of injecting properties to an object is 
   called 
  Dependency injection.
   We have three types of Dependency injection
    1)  Constructor Injection
    2)  Setter/Getter Injection
    3)  Interface Injection
   Spring will support only Constructor Injection and Setter/Getter Injection.

전체 기사 IOC전체 기사 DI 읽기


0

1) DI는 Child-> obj이며 parent-obj에 따라 다릅니다. 동사가 중요합니다. 2) IOC는 Child-> obj 플랫폼에서 수행됩니다. 플랫폼은 학교, 대학, 댄스 수업이 될 수 있습니다. 다음은 플랫폼 공급자마다 다른 의미의 활동입니다.

실제적인 예 :`

//DI
child.getSchool();
//IOC
child.perform()// is a stub implemented by dance-school
child.flourish()// is a stub implemented by dance-school/school/

`

-AB


0

이 질문에 관해서는 위키가 이미 상세하고 이해하기 쉬운 설명을 제공했다고 말합니다. 여기서 가장 중요한 것을 인용하겠습니다.

IoC 구현

객체 지향 프로그래밍에는 반전 제어를 구현하는 몇 가지 기본 기술이 있습니다. 이것들은:

  1. 서비스 로케이터 패턴 사용 예를 들어 의존성 주입 사용 생성자 주입 매개 변수 주입 세터 주입 인터페이스 주입;
  2. 상황에 맞는 조회 사용
  3. 템플릿 방법 디자인 패턴 사용;
  4. 전략 디자인 패턴 사용

의존성 주입에 관해서

의존성 주입은 한 오브젝트 (또는 정적 메소드)가 다른 오브젝트의 종속성을 제공하는 기술입니다. 종속성은 사용할 수있는 개체 (서비스)입니다. 주입이란 의존성을 종속 오브젝트 (클라이언트)에 전달하는 것입니다.


0

IoC 개념은 절차 적 프로그래밍 시대에 처음 들었습니다. 따라서 역사적 맥락에서 IoC는 통제 흐름 의 소유권 역전, 즉 기능 자체인지 또는 외부 엔티티로 전환해야하는지에 따라 원하는 순서로 기능을 호출 할 책임이있는 사람에 대해 이야기 했습니다.

그러나 OOP가 등장하면 사람들은 제어 흐름과는 별도로 응용 프로그램이 개체 생성 및 관계와 관련된 OOP 컨텍스트에서 IoC에 대해 이야기하기 시작했습니다. 이러한 응용 프로그램은 (제어 흐름 대신) 객체 생성의 소유권 을 반전 시키고 싶었 으며 객체 생성, 객체 수명주기 및 애플리케이션 객체의 종속성 주입을 담당하는 컨테이너가 필요했기 때문에 애플리케이션 객체가 다른 구체적인 객체를 생성하지 않아도됩니다.

그런 의미에서 DI는 제어 흐름에 관한 것이 아니기 때문에 Io C 와 동일 하지 않지만 일종의 Io *입니다 . 즉, 객체 생성 소유권의 반전입니다.

DI와 IoC를 설명 할 때 어떤 문제가 있습니까?


0

IoC 일명 Inversion of Control은 Spring 컨테이너가 수행하는 인스턴스 생성을 제어합니다. 객체 생성 및 생성을위한 제어는 컨테이너에 의해 처리됩니다. 컨테이너는 객체를 생성하여 애플리케이션에 주입합니다.

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