views:

217

answers:

5

In an OO component, when you have only one implementation available for an class and that class is not 'published' to other components, is it still advisable to have an interface and work with the interface instead?

I am fully aware of 'programming to an interface' design principle and also use it extensively.

Lately, I have been observing that most of the time a different implementation (although possible and would make sense) is never needed. As a result of always working with interfaces, the application code would have a fair amount of interfaces with just one implementation for each and the interface seems sort of an overhead.

Instead, is it preferable to just work with the concrete class and introduce the interface only when a second implementation is needed? Anyway, nowadays extracting an interface using IDEs is a breeze. And when the new interface is introduced, references to the old concrete class can be changed to use the new interface instead.

What do you think?

+6  A: 

Creating interfaces for concrete types is a delicate balancing act as you can easily create an interface explosion that provides no benefit and only complicates the domain space with redundant types.

My rule of thumb is to only create interfaces for types that are part of a public-facing API. All types that are dedicated to the implementation of the API and are never exposed from the API don't need an interface.

Andrew Hare
+1 b/c when moving things from not-using-an-interface to using-an-interface, it may well be impossible if it's part of your public API and you've released your code to external users.
Shin
+13  A: 

One reason I continue to program to an interface even with only one implementation is because it makes writing my tests a lot easier. I can set up proxies to test whatever I want to test and I don't have to worry about tight coupling.

This isn't always going to be advisable, but it's something worth thinking about when you're trying to decide. Do you think you'll need to extensively test around this class/object? If you think you will be it can be a lot easier dealing with the interface as opposed to the concrete class.

The alternative to that would be to not use the interface and subclass the concrete class, which works too, but again it depends.

Joseph
Agreed, I've been lately going off of 'what is the most testable and repeatable solution'? Thinking of that has allowed my codebase to be much simpler and at the same time very much driven, on the most important fronts, by interfaces.
nyxtom
Both EasyMock and JMock support class mocking so the testing argument is a mute one imho.
Nick Holt
This tend to put you in interface hell. If you don't need to declare your methods final, you can use easymock's classextension. If that's not an option, you can use powermock. Today there's no excuse to add interfaces just to make testing easier. At least not in the circumstances mentioned above.
Buhb
If you're in Interface Hell, you're probably not using ReSharper. Go To Implementation makes the pain go away. :)
TrueWill
There are more issues with interface hell than the one that is solved with "Go To Implementation". Adding a public method means adding it in two places. You need to declare something twice instead of once, which is a waste. Apart from that, the mere existence of an interface communicates that the implementing class(es) have a role, and future developers might question if a newly added public method should be part of that role or not.
Buhb
+3  A: 

Interfaces should be evolved, not created. You should have a specific need for an interface before creating one. If you haven't needed more than one implementation, you don't need an interface. Always remember, YAGNI

Kevin
I agree. Just remember to put your customer hat on when developing - if your class will be used by others they will curse you if you don't provide an interface. You may not need it, but they will if the class has any functionality / dependencies of significance.
SingleShot
@SingleShot Agreed, it depends on the type of software you're writing. A lot of "application" software isn't written with external actors in mind
Kevin
A: 

To my knowledge, there are three situations where an interface is justified:

  1. It's part of the architecture (I admit this one isn't very well defined).
  2. You have more than 1 implementation.
  3. It's a public interface.

Don't be afraid to use concrete classes. Don't mechanically generate an interface for every single class.

Buhb
A: 

In addition to the good answers given already (ease of testing and public APIs) I like using interfaces because it makes it easier to focus on "what" your classes should be doing than "how" they are doing it.

Nate