IoC 컨테이너로 팔아주세요


17

코드에서 IoC 컨테이너를 사용하는 것이 좋습니다. 동기는 간단하다. 다음 의존성 삽입 코드를 사용하십시오.

class UnitUnderTest
{
    std::auto_ptr<Dependency> d_;
public:
    UnitUnderTest(
        std::auto_ptr<Dependency> d = std::auto_ptr<Dependency>(new ConcreteDependency)
    ) : d_(d)
    {
    }
};


TEST(UnitUnderTest, Example)
{
    std::auto_ptr<Dependency> dep(new MockDependency);
    UnitUnderTest uut(dep);
    //Test here
}

으로:

class UnitUnderTest
{
    std::auto_ptr<Dependency> d_;
public:
    UnitUnderTest()
    {
        d_.reset(static_cast<Dependency *>(IocContainer::Get("Dependency")));
    }
};


TEST(UnitUnderTest, Example)
{
    UnitUnderTest uut;
    //Test here
}

//Config for IOC container normally
<Dependency>ConcreteDependency</Dependency>

//Config for IOC container for testing
<Dependency>MockDependency</Dependency>

(위는 물론 가상 C ++ 예제입니다)

나는 이것이 의존성 생성자 매개 변수를 제거하여 클래스의 인터페이스를 단순화한다는 데 동의하지만, 두 가지 이유로 치료법이 질병보다 나쁘다고 생각합니다. 첫째, 이것은 나에게 큰 것이므로 프로그램을 외부 구성 파일에 종속시킵니다. 단일 바이너리 배포가 필요한 경우 이러한 종류의 컨테이너를 사용할 수 없습니다. 두 번째 문제는 이제 API가 약하고 더 나쁘고 문자열 형식이라는 것입니다. 증거 (이 가상의 예에서)는 IoC 컨테이너에 대한 문자열 인수이며 결과에 대한 캐스트입니다.

그래서 .. 이런 종류의 용기를 사용하면 다른 이점이 있습니까? 아니면 용기를 추천하는 것에 동의하지 않습니까?


1
샘플 코드는 IoC 구현의 정말 나쁜 예처럼 보입니다. C #에만 익숙하지만 C ++에서 생성자 주입 및 프로그래밍 방식 구성을 사용할 수있는 방법이 있습니까?
rmac

답변:


12

많은 층과 움직이는 부분이 많은 대규모 응용 분야에서는 장점과 비교할 때 아주 작은 단점이 있습니다.

컨테이너는 클래스의 "인터페이스 단순화"를 수행하지만 매우 중요한 방식으로 수행됩니다. 컨테이너는 종속성 주입으로 인해 발생하는 문제에 대한 솔루션으로, 개체 그래프와 기능 영역을 통해 모든 곳에서 종속성을 전달해야합니다. 당신은 여기에 하나의 작은 예를 가질 수있다 하나 개의 종속 -이 객체가 세 의존성, 그것은에 의존 여러 개체를 가지고에 의존 객체한다면 어떨까요 에, 그래서를? 컨테이너가 없으면 종속성 체인의 맨 위에있는 객체가 전체 응용 프로그램의 모든 종속성을 추적해야합니다.

다른 종류의 용기도 있습니다. 모두 문자열로 입력 된 것은 아니며 구성 파일이 필요한 것은 아닙니다.


3
그러나 큰 프로젝트는 이미 언급 한 문제를 악화 시킵니다. 프로젝트가 크면 구성 파일이 큰 의존성 자석이되어 런타임에 오타가 정의되지 않은 동작으로 이어지는 것이 훨씬 쉬워집니다. (즉, 구성 파일에 오타가 있으면 잘못된 유형이 반환되면 캐스트로 인해 정의되지 않은 동작이 발생합니다). 종속성의 종속성에 대해서는 여기에서 중요하지 않습니다. 생성자가 생성을 처리하거나 테스트에서 최상위 수준의 종속성을 모방합니다.
Billy ONeal

... 계속 ... 프로그램을 테스트하지 않을 때 각 단계에서 기본 구체적인 종속성이 인스턴스화됩니다. 다른 종류의 컨테이너를 예로 들면 몇 가지 예가 있습니까?
Billy ONeal

4
TBH DI 구현에 대한 경험이 많지 않지만 .NET에서 MEF를 살펴보십시오. .NET에서 문자열 유형을 지정할 필요는 없으며 구성 파일이 없으며 인터페이스의 구체적인 구현이 "등록"되어 있습니다. 수업 자체에. BTW, 당신이 말할 때 : "생성자가 그들을 만들어 돌봐"-그것이 당신이하고있는 일이라면 (일명 "가난한 사람의 생성자 주입") 컨테이너가 필요하지 않습니다. 컨테이너에 비해 컨테이너의 장점은 컨테이너가 모든 해당 종속성에 대한 정보를 중앙 집중화한다는 것입니다.
nlawalker

마지막 코멘트 +1 - 마지막 문장 대답은 :가
빌리 ONeal

1
전체 요점을 파악하는 데 도움이 된 큰 대답. 요점은 보일러 플레이트를 단순화하는 것이 아니라 종속성 체인의 맨 위에있는 요소를 맨 아래에있는 요소만큼 순진하게 만드는 것입니다.
Christopher Berman

4

Java의 Guice IoC 프레임 워크는 구성 파일이 아니라 구성 코드 에 의존 합니다 . 즉, 구성은 실제 응용 프로그램을 구성하는 코드와 다르지 않으며 리팩터링 등이 가능합니다.

Guice는 구성이 올바르게 된 Java IoC 프레임 워크라고 생각합니다.


C ++에 대한 비슷한 예가 있습니까?
Billy ONeal

@ 빌리, 말할 수있는 C ++에 익숙하지 않습니다.

0

이 위대한 SO 대답 하여 벤 Scheirman는 C #에서 몇 가지 코드 예제를 자세히 설명; IoC 컨테이너 (DI)의 장점은 다음과 같습니다.

  • 종속성 체인이 중첩 될 수 있으며 수동으로 연결하는 것이 까다로워집니다.
  • Aspect 지향 프로그래밍을 사용할 수 있습니다 .
  • 선언 및 중첩 데이터베이스 트랜잭션.
  • 선언적이고 중첩 된 작업 단위.
  • 벌채 반출.
  • 사전 / 사후 조건 (계약에 의한 설계).

1
간단한 생성자 주입으로 이러한 것들을 구현할 수없는 방법을 모르겠습니다.
Billy ONeal

좋은 디자인으로 생성자 주입 또는 다른 방법으로 충분할 수 있습니다. 이러한 IoC 컨테이너의 장점은 특정 경우에만있을 수 있습니다. WPF 프로젝트에서 INotifyPropertyChanged와 함께 제공된 예는 그러한 예 중 하나입니다.
dodgy_coder
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.