문제

저는 최근 StructureMap을 사용하고 있으며 경험을 완전히 즐겼습니다.그러나 나는 모든 것을 인터페이스하는 것에 쉽게 빠져들고 생성자로 인터페이스의 보트로드를 받아들이는 클래스로 끝날 수있는 방법을 볼 수 있습니다.의존성 주입 프레임 워크를 사용할 때 실제로 큰 문제는 아니지만, 인터페이스를 위해 인터페이스 할 필요가없는 특정 속성이 여전히 있다고 느낍니다.

클래스에 속성을 추가하는 것보다 인터페이스 할 대상에 대한 선을 어디에서 그리나요?

도움이 되었습니까?

해결책

디자인에 대해 생각해보세요.DI를 사용하면 구성 변경을 통해 코드 기능을 변경할 수 있습니다.또한 클래스 간의 종속성을 분리하여 개체를 더 쉽게 격리하고 테스트 할 수 있습니다.이것이 의미가있는 부분과 그렇지 않은 부분을 결정해야합니다.확실한 대답이 없습니다.

좋은 경험 법칙은 테스트하기가 너무 어려우면 단일 책임과 정적 종속성에 문제가 있다는 것입니다.단일 기능을 수행하는 코드를 클래스로 분리하고 인터페이스를 추출하고 DI 프레임 워크를 사용하여 런타임에 올바른 인스턴스를 삽입하여 정적 종속성을 끊습니다.이렇게하면 두 부분을 개별적으로 테스트하는 것이 간단 해집니다.

다른 팁

의존성 주입의 주된 문제는 느슨하게 결합 된 아키텍처의 모양을 제공하지만 실제로는 그렇지 않다는 것입니다.

실제로하는 일은 컴파일 시간에서 런타임으로이 커플 링을 이동하는 것입니다.하지만 여전히 클래스 A가 작동하기 위해 인터페이스 B가 필요한 경우 인터페이스 B를 구현하는 클래스 인스턴스를 제공해야합니다. p>

종속성 주입은 기본 코드를 다시 컴파일하지 않고 동적으로 변경해야하는 애플리케이션 부분에만 사용해야합니다.

Inversion of Control 패턴에 유용하다고 본 사용 :

  • 플러그인 아키텍처. 따라서 올바른 진입 점을 만들어 제공해야하는 서비스에 대한 계약을 정의 할 수 있습니다.
  • 워크 플로와 유사한 아키텍처. 컴포넌트의 출력을 다른 컴포넌트의 입력에 동적으로 연결하는 여러 컴포넌트를 연결할 수 있습니다.
  • 클라이언트 별 애플리케이션. 프로젝트의 "기능"세트에 대한 비용을 지불하는 다양한 클라이언트가 있다고 가정 해 보겠습니다. 종속성 주입을 사용하면 핵심 구성 요소와 클라이언트가 지불 한 기능 만 제공하는 일부 "추가"구성 요소 만 쉽게 제공 할 수 있습니다.
  • 번역. 일반적으로 번역 목적으로 수행되지는 않지만 응용 프로그램에서 필요에 따라 다른 언어 파일을 "주입"할 수 있습니다. 여기에는 필요에 따라 RTL 또는 LTR 사용자 인터페이스가 포함됩니다.
<인용구>

종속성 주입은 재 컴파일하지 않고 동적으로 변경해야하는 애플리케이션 기본 코드

DI는 외부 리소스 (데이터베이스, 웹 서비스, xml 파일, 플러그인 아키텍처)에서 코드를 분리하는 데 사용해야합니다.코드에서 논리를 테스트하는 데 걸리는 시간은 데이터베이스에 의존하는 구성 요소를 테스트하는 경우 많은 회사에서 거의 불가능할 것입니다.

대부분의 응용 프로그램에서 데이터베이스는 동적으로 변경되지 않지만 (할 수 있지만) 일반적으로 응용 프로그램을 특정 외부 리소스에 바인딩하지 않는 것이 거의 항상 좋은 습관입니다.자원 변경과 관련된 양은 적어야합니다 (데이터 액세스 클래스는 메소드에서 하나 이상의 순환 복잡도를 갖는 경우는 드뭅니다).

'단순한 클래스에 속성 추가'란 무엇을 의미하나요?

내 경험 법칙은 수업 단위를 테스트 가능하게 만드는 것입니다.클래스가 다른 클래스의 구현 세부 정보에 의존하는 경우 클래스를 격리하여 테스트 할 수있는 지점까지 리팩토링 / 추출해야합니다.

편집 : 생성자에서 인터페이스의 보트로드를 언급합니다.대신 세터 / 게터를 사용하는 것이 좋습니다.장기적으로는 유지 관리가 훨씬 쉬워집니다.

I do it only when it helps with separation of concerns.

Like maybe cross-project I would provide an interface for implementers in one of my library project and the implementing project would inject whatever specific implementation they want in.

But that's about it... all the other cases it'd just make the system unnecessarily complex

Even with all the facts and processes in the world.. every decision boils down to a judgment call - Forgot where I read that
I think it's more of a experience / flight time call. Basically if you see the dependency as a candidate object that may be replaced in the near future, use dependency injection. If I see 'classA and its dependencies' as one block for substitution, then I probably won't use DI for A's deps.

The biggest benefit is that it will help you understand or even uncover the architecture of your application. You'll be able to see very clearly how your dependency chains work and be able to make changes to individual parts without requiring you to change things that are unrelated. You'll end up with a loosely coupled application. This will push you into a better design and you'll be surprised when you can keep making improvements because your design will help you keep separating and organizing code going forward. It can also facilitate unit testing because you now have a natural way to substitute implementations of particular interfaces.

There are some applications that are just throwaway but if there's a doubt I would go ahead and create the interfaces. After some practice it's not much of a burden.

Another item I wrestle with is where should I use dependency injection? Where do you take your dependency on StructureMap? Only in the startup application? Does that mean all the implementations have to be handed all the way down from the top-most layer to the bottom-most layer?

I use Castle Windsor/Microkernel, I have no experience with anything else but I like it a lot.

As for how do you decide what to inject? So far the following rule of thumb has served me well: If the class is so simple that it doesn't need unit tests, you can feel free to instantiate it in class, otherwise you probably want to have a dependency through the constructor.

As for whether you should create an interface vs just making your methods and properties virtual I think you should go the interface route either if you either a) can see the class have some level of reusability in a different application (i.e. a logger) or b) if either because of the amount of constructor parameters or because there is a significant amount of logic in the constructor, the class is otherwise difficult to mock.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top