3

When using depending injection, you generally pass everything around as an interface (perhaps with the exception of primitives and strings). That allows you to easily chance the behavior, without changing the implementation.

Is there ever a case where I should not be passing some complex object through an interface though?

8

This depends on the programming language, the availability of a mocking framework and your need for mocking those complex objects. For C# and Java, there are frameworks available which allow you to mock out classes without creating interfaces first. (In the environment where I work, we don't use any of those frameworks, so whenever we have to mock a class for a unit test, we are going to create an interface.) In C++, you can avoid the need for interface-based mocking by injecting your "complex class" as a template parameter into every other component which is going to use it (the drawback is you have to templatize those classes, which means a certain amount of overhead).

In weakly typed languages there's often not even a language construct "interface" because you can replace an object of a class just by an object of a different type as long as the replacement fulfills the implicit contract (i.e. provides methods with correct names and signature).

Furthermore, I agree that DI does not work well with infrastructure classes like "strings". See this former PSE question & my answer to it.

I would like to add that your question sounds like "shall I always provide an interface 'just in case'". IMHO it is better to follow the YAGNI principle, start without an interface, and as soon as you need one, maybe for mocking purposes, refactor your code and introduce the interface afterwards.

3

Any case where there is only ever going to be a single implementation.

Any case where you are passing an instance of a derived type, rather than an instance that fulfills a particular interface.

  • When can you know there is only going to be a single implementation? Maybe there is only one right now, but I'm pretty stupid, and I always assume that someone will come later and think of a better version. – David Grinberg Sep 19 '14 at 18:22
  • 1
    @dgrin91 - things like strings. Nobody is going to make a "new" string. Likewise if you're implementing something that represents a Date or an Atom, things where people aren't just going to make up or redefine some concept. The concept is fixed by reality. – Telastyn Sep 19 '14 at 18:25
  • @Telastyn Why? What if I think of a better (ie more optimized) string implementation? For example, in Java Strings implement CharSequence. So if I think of some new optimization of String, I can easily swap it in if the program uses DI with CharSequences. – David Grinberg Sep 19 '14 at 18:28
  • 2
    When you've actually got a second implementation, refactor so that you're using an interface. – Robert Harvey Sep 19 '14 at 18:31
  • @Dgrin91 - What are the odds of that? Program design is a series of trade-offs. What is the odds that you'll need to swap out your string implementation, versus the cost of writing all of the boilerplate code that allows you to do that easily (and the maintenance cost of people misunderstanding or misusing the CharSequence)? And if you wrote the original class, what are the odds that you need a different implementation as opposed to refactoring the existing class to use the better implementation? – Telastyn Sep 19 '14 at 18:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.