종속성 주입 패턴을 사용하는 것이 부적절한 경우는 언제입니까?


124

자동화 테스트를 배우고 사랑했기 때문에 거의 모든 프로젝트에서 의존성 주입 패턴을 사용하는 것을 발견했습니다. 자동화 된 테스트 작업시이 패턴을 사용하는 것이 항상 적절합니까? 의존성 주입을 피해야하는 상황이 있습니까?


1
관련 (아마 중복되지 않음) - stackoverflow.com/questions/2407540/...
Steve314

3
Golden Hammer 안티 패턴과 약간 비슷합니다. en.wikipedia.org/wiki/ 안티 패턴
Cuga

답변:


123

기본적으로 의존성 주입은 객체의 특성에 대해 (보통은 아니지만 항상 유효한 것은 아닙니다) 가정합니다. 잘못된 경우 DI가 최상의 솔루션이 아닐 수 있습니다.

  • 첫째, 가장 기본적으로 DI는 객체 구현의 긴밀한 결합이 항상 나쁘다고 가정합니다 . 이것이 의존성 역전 원칙의 본질이다 : "결석에 의존해서는 안되며 추상화에만 의존해야한다".

    이것은 구체적인 구현에 대한 변경에 따라 변경 될 종속 개체를 닫습니다. 출력이 파일로 이동 해야하는 경우 ConsoleWriter에 따라 클래스를 변경해야하지만 Write () 메서드를 노출하는 IWriter에만 의존하는 클래스는 현재 사용중인 ConsoleWriter를 FileWriter 및 종속 클래스는 차이를 알지 못합니다 (Liskhov 대체 원칙).

    그러나 디자인이 모든 유형의 변경에 대해 폐쇄 될 수는 없습니다. IWriter 인터페이스의 디자인 자체가 변경되면 Write ()에 매개 변수를 추가하기 위해 구현 객체 / 메소드 및 해당 사용법 위에 추가 코드 객체 (IWriter 인터페이스)를 변경해야합니다. 실제 인터페이스의 변경이 상기 인터페이스의 구현에 대한 변경보다 더 가능성이 높으면, 느슨한 결합 (및 DI 결합의 느슨하게 결합 된 종속성)이 해결하는 것보다 더 많은 문제를 야기 할 수 있습니다.

  • 둘째, 그리고 결론적으로, DI는 의존 클래스가 의존성을 생성하기에 좋은 장소라고 절대 가정하지 않는다 . 이것은 단일 책임 원칙으로갑니다. 종속성을 생성하고 사용하는 코드가있는 경우 종속 클래스가 SRP를 위반하여 변경 (사용 또는 구현 변경)해야하는 두 가지 이유가 있습니다.

    그러나 DI에 대한 간접 레이어를 추가하는 것은 존재하지 않는 문제에 대한 해결책이 될 수 있습니다. 종속성에서 논리를 캡슐화하는 것이 논리적이지만 해당 논리가 종속성의 유일한 구현이라면 종속성의 느슨하게 결합 된 해상도 (사출, 서비스 위치, 팩토리)를 코딩하는 것보다 더 고통 스럽습니다. 그냥 사용 new하고 잊어 버리십시오.

  • 마지막으로, DI는 그 특성상 모든 의존성과 구현에 대한 지식을 중앙 집중화합니다 . 이것은 주입을 수행하는 어셈블리가 가져야하는 참조 수를 증가 시키며 대부분의 경우 실제 종속 클래스의 어셈블리에 필요한 참조 수를 줄이지 않습니다.

    SOMETHING, SOMEWINGE는 "도트를 연결"하고 해당 종속성을 만족시키기 위해 종속 인터페이스, 종속성 인터페이스 및 종속성 구현에 대한 지식이 있어야합니다. DI는 모든 지식을 IoC 컨테이너 또는 의존성을 수화 (또는 팩토리 방식으로 제공)해야하는 기본 형식 또는 컨트롤러와 같은 "주요"개체를 생성하는 코드에서 매우 높은 수준으로 배치하는 경향이 있습니다. 이를 통해 앱의 상위 레벨에 꼭 필요한 코드와 어셈블리 참조를 많이 넣을 수 있습니다. 실제 종속 클래스에서 코드를 숨기려면이 지식 만 있으면됩니다. 이 지식을 얻는 가장 좋은 장소; 그것이 사용되는 곳).

    또한 일반적으로 코드에서 아래쪽에서 상기 참조를 제거하지 않습니다. 종속물은 여전히 ​​의존성에 대한 인터페이스를 포함하는 라이브러리를 참조해야하며, 다음 세 위치 중 하나에 있습니다.

    • 모든 응용 프로그램 중심이되는 단일 "인터페이스"어셈블리
    • 각각은 기본 구현과 함께 종속성이 변경 될 때 종속 항목을 다시 컴파일 할 필요가 없다는 이점을 제거합니다.
    • 응집력이 높은 어셈블리의 하나 또는 두 개의 어셈블리는 어셈블리 수를 늘리고 "전체 빌드"시간을 크게 늘리고 응용 프로그램 성능을 저하시킵니다.

    이 모든 것이 다시없는 곳에서 문제를 해결하기 위해 다시 한 번.


1
SRP = 다른 사람이 궁금해하는 단일 책임 원칙.
Theodore Murdock

1
그렇습니다. LSP는 Liskov 대체 원칙입니다. A에 대한 종속성이 주어지면 다른 변경없이 A에서 파생되는 B가 종속성을 충족시킬 수 있어야합니다.
KeithS

의존성 주입은 특히 클래스 D 등에서 클래스 B에서 클래스 A를 가져와야하는 경우에 특히 도움이됩니다 (이 경우에만). DI 프레임 워크는 가난한 사람 주입보다 어셈블리 부풀림이 덜 발생할 수 있습니다. 또한 DI로 인해 병목 현상이 발생하지 않았습니다. 코드를 항상 최적화 할 수 있기 때문에 유지 관리 비용을 고려하고 CPU 비용을 고려하지 마십시오. 그러나 이유없이이를 수행하는 데에는 비용이 있습니다
GameDeveloper

또 다른 가정은 "의존성이 바뀌면 어디에서나 변한다"는 것인가? 그렇지 않으면 어쨌든 모든 소비 수업을 살펴 ​​봐야합니다
Richard Tingle

3
이 답변은 의존성 주입과 하드 코딩의 테스트 가능성 영향을 해결하지 못합니다. 또한 명시 적 종속성 원칙 (참조 deviq.com/explicit-dependencies-principle를 )
ssmith

30

의존성 주입 프레임 워크 외부에서, 의존성 주입 (생성자 주입 또는 세터 주입을 통한)은 거의 제로섬 게임입니다. 객체 A와 의존성 B 사이의 연결을 줄이지 만 이제 A의 인스턴스가 필요한 모든 객체는 이제 또한 객체 B를 구성하십시오.

A와 B 사이의 연결을 약간 줄 였지만 A의 캡슐화를 줄이고 A와 A의 종속성에 연결하여 A의 인스턴스를 구성해야하는 클래스 간의 연결을 늘 렸습니다.

따라서 프레임 워크가없는 종속성 주입은 도움이되므로 거의 해롭지 않습니다.

그러나 추가 비용은 종종 정당화하기 쉽다. 클라이언트 코드가 객체 자체보다 의존성을 구성하는 방법에 대해 더 많이 알고 있다면 의존성 주입은 실제로 커플 링을 줄인다. 예를 들어, 스캐너는 입력을 구문 분석하기 위해 입력 스트림을 가져 오거나 구성하는 방법 또는 클라이언트 코드가 입력을 구문 분석하려는 소스에 대해 잘 모르므로 입력 스트림의 생성자 주입이 확실한 솔루션입니다.

모의 의존성을 사용하기 위해서는 테스트가 또 다른 정당화입니다. 즉, 의존성을 주입 할 수 있도록 테스트에만 사용되는 추가 생성자를 추가해야합니다. 대신 의존성을 항상 주입해야하도록 생성자를 변경하는 경우 갑자기 의존성을 생성하기 위해 의존성의 종속성에 대해 알아야합니다. 직접적인 의존성, 어떤 작업도 할 수 없습니다.

도움이 될 수 있지만 각 의존성에 대해 스스로에게 물어봐야하며, 테스트 가치가 비용의 가치가 있으며, 테스트하는 동안이 의존성을 조롱하고 싶습니까?

의존성 주입 프레임 워크가 추가되고 의존성 구성이 클라이언트 코드가 아닌 프레임 워크에 위임되면 비용 / 이익 분석이 크게 변경됩니다.

의존성 주입 프레임 워크에서 트레이드 오프는 약간 다릅니다. 의존성을 주입하여 잃어버린 것은 어떤 구현에 의존하고 있는지 쉽게 알 수 있고 자동화 된 해결 프로세스에 의존하는 의존성을 결정하는 책임을 바꾸는 것입니다 (예 : @ Inject'ed Foo가 필요한 경우) , @Provides Foo를 제공하고 주입 된 종속성을 사용할 수있는 것) 또는 각 리소스에 사용해야하는 공급자를 규정하는 일부 고급 구성 파일 또는 두 가지의 하이브리드에 대한 것 (예 : 필요한 경우 구성 파일을 사용하여 재정의 할 수있는 종속성에 대한 자동화 된 해결 프로세스 여야합니다.

생성자 주입에서와 같이 그렇게하는 것의 장점은 비용과 매우 유사하다는 결론을 내릴 수 있습니다. 누가 의존하는 데이터를 제공하는지 누가 여러 가지 가능성이 있는지 알 필요가 없습니다. 제공자는 제공자를 체크인하기 위해 선호하는 순서를 알 필요가 없으며 모든 잠재적 제공자 등의 데이터 검사가 필요한 모든 위치를 확인해야합니다. 모든 위치는 종속성 주입에 의해 높은 수준으로 처리되므로 플랫폼.

개인적으로 DI 프레임 워크에 대한 경험이 많지는 않지만, 필요한 데이터 또는 서비스의 올바른 공급자를 찾는 데 어려움이 두통보다 비용이 높을 때 비용보다 더 많은 이점을 제공한다는 인상이 있습니다. 어떤 코드가 실패했는지, 어떤 코드가 로컬에서 나쁜 데이터를 제공했는지 나중에 코드에서 나중에 실패하게하는 원인을 즉시 알지 못하는 경우.

경우에 따라 DI 프레임 워크가 현장에 나타 났을 때 의존성을 모호하게하는 다른 패턴 (예 : 서비스 로케이터)이 이미 채택되었고 그 가치가 입증 된 경우도있었습니다. 더 적은 상용구 코드, 또는 실제로 사용중인 제공자를 판별해야 할 때 제공자의 종속성을 가릴 수있는 가능성이 줄어 듭니다.


6
테스트에서 의존성 조롱과 "종속성 의존성 의존성에 대해 알아야한다"에 대한 간단한 설명 만하면됩니다. 그것은 사실이 아닙니다. 모의가 주입되는 경우 구체적인 구현의 종속성을 알거나 신경 쓸 필요가 없습니다. 테스트 대상 클래스 의 직접적인 종속성에 대해 알아야만 모의자가 만족합니다.
에릭 킹

6
당신은 오해, 당신이 모형을 주입 할 때 말하는 것이 아니라 실제 코드에 대해 이야기하고 있습니다. 의존성 B를 갖는 의존성 B를 갖는 클래스 A를 고려하십시오. 차례로 의존성 D를 갖는 의존성 C를가집니다. DI가 없으면, A는 B를 구성하고, B는 C를 구성하고, C는 D를 구성합니다. B를 구성하려면 먼저 C를 구성하고 C를 구성하려면 먼저 D를 구성해야합니다. 따라서 클래스 A는 B를 구성하기 위해 종속성 종속성의 종속성 인 D에 대해 알아야합니다. 이로 인해 과도한 결합이 발생합니다.
시어 도어 머독

1
의존성을 주입 할 수있는 테스트에만 추가 생성자를 사용하는 데 많은 비용이 들지 않습니다. 내가 말한 것을 수정하려고 노력할 것입니다.
시어 도어 머독

3
의존성 주입은 제로섬 게임에서만 의존성을 움직입니다. 의존성을 기존 프로젝트 (주 프로젝트)로 옮깁니다. 예를 들어 네임 스페이스 등으로 구체적인 클래스를 지정하여 종속성을 런타임에만 해결하기 위해 규칙 기반 접근 방식을 사용할 수도 있습니다. 나는 이것이 순진한 대답이라고 말해야한다
Sprague

2
@Sprague Dependency injection은 적용하지 않아야 할 경우에 적용하면 약간의 음수 게임에서 종속성을 따라 이동합니다. 이 답변의 목적은 의존성 주입이 본질적으로 좋지 않다는 것을 사람들에게 상기시키는 것입니다. 그것은 올바른 상황에서 믿을 수 없을만큼 유용한 디자인 패턴이지만 정상적인 상황에서는 (적어도 내가 일한 프로그래밍 영역에서) 정당하지 않은 비용입니다 , 일부 도메인에서는 다른 도메인보다 더 자주 유용하다는 것을 알고 있습니다. DI는 때때로 유행어가되고 그 자체로 끝이납니다.
Theodore Murdock

11
  1. 데이터베이스 엔티티를 작성하는 경우 컨트롤러에 대신 주입 할 팩토리 클래스가 있어야합니다.

  2. int 또는 long과 같은 기본 객체를 만들어야하는 경우 또한 날짜, 안내 등과 같은 대부분의 표준 라이브러리 객체를 "손으로"작성해야합니다.

  3. 구성 문자열을 주입하려면 일부 구성 오브젝트를 주입하는 것이 좋습니다. 일반적으로 단순 유형을 의미있는 오브젝트로 랩핑하는 것이 좋습니다. int temperatureInCelsiusDegrees-> CelciusDeegree temperature)

그리고 의존성 주입 대안으로 Service locator를 사용하지 마십시오. 안티 패턴, 자세한 정보 : http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx


모든 요점은 완전히 사용하지 않고 다른 형태의 주입을 사용하는 것입니다. 링크의 경우 +1
Jan Hudec

3
Service Locator는 안티 패턴이 아니며 블로그를 연결 한 사람은 패턴 전문가가 아닙니다. 그가 StackExchange로 유명하다는 것은 소프트웨어 설계에 대한 일종의 장애입니다. Martin Fowler (Enterprise Application Architecture의 스테이플 패턴 작성자)는이 문제에 대해보다 합리적인 견해를 가지고 있습니다. martinfowler.com/articles/injection.html
Colin

1
@Colin은 반대로 Service Locator는 반 패턴으로 가장 확실하며 여기에 이유가 있습니다.
Kyralessa

@Kyralessa-DI 프레임 워크는 내부적으로 서비스 로케이터 패턴을 사용하여 서비스를 찾는다는 것을 알고 있습니까? StackExchange가 일부 사람들이 덤프하고 싶어하는 증오에도 불구하고 두 가지 모두 적절한 상황이 있으며 반 패턴이 아닙니다.
콜린

물론 내 차는 내부적으로 피스톤과 점화 플러그를 사용하지만 자동차를 운전하고 싶어하는 일반인에게는 좋은 인터페이스가 아닌 다른 것들을 사용합니다.
Kyralessa

8

프로젝트를 유지 관리하고 테스트 할 수있게하여 아무것도 얻지 못하는 경우.

진심으로, 나는 일반적으로 IoC와 DI를 좋아하며, 98 %의 시간이 그 패턴을 반드시 사용할 것이라고 말하고 싶습니다. 로직을 구현에서 분리하므로 다른 팀 구성원과 다른 프로젝트에서 코드를 반복해서 재사용 할 수있는 다중 사용자 환경에서 특히 중요합니다. 로깅은 이것의 대표적인 예입니다. 클래스에 주입 된 ILog 인터페이스는 로깅 프레임 워크를 단순히 플러그인하는 것보다 유지 관리가 가능합니다. 다른 프로젝트가 동일한 로깅 프레임 워크를 사용한다는 보장이 없기 때문입니다 (사용하는 경우) 하나!).

그러나 적용 가능한 패턴이 아닌 경우가 있습니다. 예를 들어, 재정의 불가능한 이니셜 라이저 (WebMethods, 나는 당신을보고 있지만 Program 클래스의 Main () 메소드는 또 다른 예)에 의해 정적 컨텍스트에서 구현되는 기능적 진입 점은 초기화시 의존성을 주입 할 수 없습니다. 시각. 또한 프로토 타입 또는 모든 버리기 조사 코드도 나쁜 후보라고 말할 수 있습니다. 일주일 이내에 코드의 대부분을 버릴 것이라고 확신한다면 DI의 이점은 거의 중장기적인 이점 (테스트 가능성 및 유지 관리 가능성)입니다. 의존성, 일반적으로 코드를 작동시키는 데 의존성을 테스트하고 격리하는 데 소비하는 시간을 보내십시오.

대체로 100 % 적용 할 수있는 방법이 없기 때문에 모든 방법론이나 패턴에 실용적인 접근 방식을 취하는 것이 합리적입니다.

주목할 것은 자동화 된 테스트에 대한 귀하의 의견입니다.이 정의는 자동화 된 기능 테스트입니다 (예 : 웹 컨텍스트에있는 경우 스크립트 된 셀레늄 테스트). 이것들은 일반적으로 코드의 내부 작동에 대해 알 필요가없는 완전 블랙 박스 테스트입니다. 단위 테스트 또는 통합 테스트를 언급하는 경우 DI 패턴은 거의 항상 이러한 종류의 화이트 박스 테스트에 의존하는 모든 프로젝트에 적용 할 수 있다고 말합니다. 예를 들어 다음과 같은 것을 테스트 할 수 있기 때문입니다. DB가 없어도 DB를 만지는 방법.


로깅에 대한 당신의 의미를 이해하지 못합니다. 확실히 모든 로거가 동일한 인터페이스를 준수하지 않으므로이 프로젝트 방식과 특정 로거 사이를 변환하기 위해 자신의 래퍼를 작성해야합니다 (로거를 쉽게 변경하려는 경우). 그 후 DI는 무엇을 제공합니까?
Richard Tingle

@RichardTingle 로깅 래퍼를 인터페이스로 정의한 다음 여러 추상화를 래핑하는 단일 로깅 클래스를 사용하는 대신 각 외부 로깅 서비스에 대해 해당 인터페이스의 간단한 구현을 작성한다고 말하고 싶습니다. 그것은 당신이 제안하는 것과 같은 개념이지만 다른 수준에서 추상화되었습니다.
Ed James

1

다른 답변은 기술적 측면에 중점을두고 있지만 실용적인 차원을 추가하고 싶습니다.

수년에 걸쳐 Dependency Injection을 도입하는 데 성공하려면 몇 가지 실용적인 요구 사항이 충족되어야한다는 결론에 도달했습니다.

  1. 소개 할 ​​이유가 있어야합니다.

    이것은 분명한 것처럼 들리지만 코드가 데이터베이스에서 물건을 가져 와서 논리없이 반환하면 DI 컨테이너를 추가하면 실제로 이익을 얻지 않고 더 복잡하게 만듭니다. 여기서 통합 테스트가 더 중요합니다.

  2. 팀은 훈련을 받고 탑승해야합니다.

    팀의 대다수가 기내에 있고 DI가 컨트롤 컨테이너의 반전을 추가하는 것이 작업을 수행하는 또 다른 방법이되고 코드 기반을 더욱 복잡하게 만드는 것을 이해하지 않는 한.

    DI가 팀의 새로운 구성원에 의해 도입 된 경우, DI를 이해하고 좋아하고 자신이 훌륭하다는 것을 보여주고 싶기 때문에 팀이 적극적으로 참여하지 않으면 실제로 품질이 저하 될 위험이 있습니다. 코드.

  3. 테스트해야합니다

    디커플링은 일반적으로 좋은 방법이지만 DI는 종속성의 해결을 컴파일 시간에서 런타임으로 이동할 수 있습니다. 잘 테스트하지 않으면 실제로 매우 위험합니다. 런타임 해결 실패는 추적 및 해결 비용이 많이들 수 있습니다.
    테스트 결과는 분명하지만 많은 팀이 DI에서 요구하는 범위까지 테스트하지는 않습니다.


1

이것은 완전한 대답이 아니라 또 다른 요점입니다.

한 번 시작하는 응용 프로그램이 있으면 웹 응용 프로그램과 같이 오랫동안 실행되는 DI가 좋습니다.

모바일 앱과 같이 여러 번 시작되고 짧은 시간 동안 실행되는 응용 프로그램이 있으면 컨테이너를 원하지 않을 것입니다.


나는 DI와 관련된 응용 프로그램의 실시간 시간을 보지 못합니다
Michael Freidgeim

@MichaelFreidgeim 컨텍스트를 초기화하는 데 시간이 걸립니다. 일반적으로 DI 컨테이너는 Spring과 같이 상당히 무겁습니다. 하나의 클래스로 hello world 앱을 만들고 Spring으로 하나 만들고 10 번 시작하면 내 말의 의미를 알 수 있습니다.
Koray Tugay

개별 DI 컨테이너의 문제처럼 들립니다. 닷넷 세계에서 나는 DI 컨테이너 필수적인 문제로 초기화 시간에 대해 듣지 못했어요
마이클 Freidgeim에게

1

기본 OOP 원칙을 사용하십시오. 상속 을 사용하여 개인 / 내부 / 보호 멤버 / 유형을 사용하여 외부에서 보호해야하는 공통 기능을 추출하고 사물을 캡슐화 (숨기기)하십시오. 강력한 테스트 프레임 워크를 사용하여 테스트 전용 코드 (예 : https://www.typemock.com/ 또는 https://www.telerik.com/products/mocking.aspx) 를 삽입 하십시오 .

그런 다음 DI로 다시 작성하고 DI에서 일반적으로 볼 수있는 코드를 비교하십시오.

  1. 더 많은 인터페이스가 있습니다 (더 많은 유형)
  2. 공용 메소드 서명의 복제본을 작성했으며이를 두 번 유지해야합니다 (일부 매개 변수를 한 번만 변경할 수 없으며 두 번 수행해야합니다. 기본적으로 모든 리팩토링 및 탐색 가능성이 더 복잡해집니다).
  3. 런타임 오류로 컴파일 오류를 옮겼습니다 (DI를 사용하면 코딩 중에 일부 종속성을 무시할 수 있으며 테스트 중에 노출되는지 확실하지 않습니다)
  4. 캡슐화를 열었습니다. 이제 보호 회원, 내부 유형 등이 공개되었습니다
  5. 전체 코드 양이 증가했습니다

DI에서 코드 품질이 거의 항상 저하되는 것을 보았습니다.

그러나 클래스 선언에서 "공개"액세스 수정 자 및 / 또는 멤버에 대한 공개 / 개인 수정자를 사용하거나 값 비싼 테스트 도구를 구매할 수없고 동시에 테스트 할 수있는 단위 테스트가 필요한 경우 통합 테스트로 교체하거나 이미 주입하고자하는 수업을위한 인터페이스가 있다면 DI가 좋은 선택입니다!

추신 : 아마도이 게시물에 대한 많은 마이너스를 얻을 것입니다. 현대 개발자의 대부분은 내부 키워드 를 사용하는 방법과 이유 및 구성 요소의 결합을 줄이는 방법을 이해하지 못하기 때문에 마침내) 코딩하고 비교하려고


0

Dependency Injection대안은 Service Locator를 사용하는 것 입니다. 서비스 로케이터는 DI 프레임 워크를 사용하지 않는 경우 이해하기 쉽고 디버그가 용이하며 객체 구성을 더 단순하게 만듭니다. 서비스 로케이터는 외부 정적 종속성 ( 예 : 데이터 액세스 계층의 모든 개체에 전달해야하는 데이터베이스) 을 관리하기 위한 좋은 패턴입니다 .

레거시 코드를 리팩토링 , 종속성 주입보다 서비스 로케이터로 리팩토링하는 것이 종종 더 쉽다. 인스턴스화를 서비스 조회로 교체 한 다음 단위 테스트에서 서비스를 위조하기 만하면됩니다.

그러나 Service Locator 에는 몇 가지 단점 이 있습니다 . 종속성은 생성 자나 설정자가 아닌 클래스의 구현에 숨겨져 있기 때문에 클래스의 depandancies를 아는 것이 더 어렵습니다. 그리고 동일한 서비스의 서로 다른 구현에 의존하는 두 개의 객체를 생성하는 것은 어렵거나 불가능합니다.

TLDR : 클래스에 정적 종속성이 있거나 레거시 코드를 리팩토링하는 경우 서비스 로케이터가 DI보다 낫습니다.


12
Service Locator는 코드에서 종속성을 숨 깁니다 . 사용하기에 좋은 패턴은 아닙니다.
Kyralessa

정적 의존성에 관해서는 인터페이스를 구현하는 외관이 두드려지는 것이 좋습니다. 이것들은 의존성 주입 될 수 있으며 정적 수류탄에 떨어집니다.
Erik Dietrich

@Kyralessa 동의합니다. 서비스 로케이터에는 많은 단점이 있으며 DI는 거의 항상 선호됩니다. 그러나 모든 프로그래밍 원칙과 마찬가지로 규칙에는 몇 가지 예외가 있다고 생각합니다.
개렛 홀

서비스 위치의 주요 사용 용도는 "전략 선택기"클래스에 사용할 전략을 찾을 수있는 충분한 논리가 제공되고 전략을 전달하거나 전달하는 전략 패턴 내에 있습니다. 이 경우에도 전략 선택기는 IoC 컨테이너가 제공하는 팩토리 메소드의 외관 일 수 있으며 동일한 로직이 제공됩니다. 당신이 그것을 깨는 이유는 가장 숨겨진 곳이 아닌 논리를 속한 곳에 두는 것입니다.
KeithS

Martin Fowler는 "(DI와 Service Locator)의 선택은 구성과 사용을 분리하는 원칙보다 덜 중요합니다"라고 말합니다. DI가 항상 더 좋다는 생각은 비약적입니다. 서비스가 전 세계적으로 사용되는 경우 DI를 사용하는 것이 더 번거롭고 부서지기 쉽습니다. 또한 DI는 구현이 런타임까지 알려지지 않은 플러그인 아키텍처에는 적합하지 않습니다. 항상 추가 인수를 Debug.WriteLine () 등에 전달하는 것이 얼마나 어색한 지 생각해보십시오!
Colin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.