views:

554

answers:

11

I think the title speaks for itself guys - why should I write an interface and then implement a concrete class if there is only ever going to be 1 concrete implementation of that interface?

+3  A: 

The question is, if there is only going to ever be one concrete implementation, should there be an interface?

Jimmeh
Correct, but that's a question, not an answer.
Jason S
@Jason: a good question is often the best answer (boy was I tempted to write that as a question ;-))
Joachim Sauer
+35  A: 

I think you shouldn't ;)

There's no need to shadow all your classes with corresponding interfaces.

Even if you're going to make more implementations later, you can always extract the interface when it becomes necessary.

Lennaert
+100 if I could, it is counter-productive to create unused interfaces everywhere. When (if) you need it, it's trivial to refactor and extract one out.
slf
Agreed. An internal class with a single implementation doesn't need an interface. The interface *might* be interesting if it forms part of an external API - so people using the interface in ways you haven't predicted aren't forced to extend your implementation...
Bill Michell
How about testing? I mean, EasyMock only creates mocks for interfaces.
folone
There is an EasyMock class extension library that lets you mock concrete classes http://easymock.org/Downloads.html
Rob Spieldenner
@folone: He didn't mention testing ;) I agree that that would be a good reason to create an interface, but there are situations where I've just subclassed the to-be-mocked class instead of creating an interface, although that might simply be considered laziness :)
Lennaert
+12  A: 

This is a question of granularity. You cannot clutter your code with unnecessary interfaces but they are useful at boundaries between layers.

Someday you may try to test a class that depends on this interface. Then it's nice that you can mock it.

I'm constantly creating and removing interfaces. Some were not worth the effort and some are really needed. My intuition is mostly right but some refactorings are necessary.

Thomas Jung
A: 

"Only Ever going to have One implementation" == famous last words

It doesn't cost much to make an interface and then derive a concrete class from it. The process of doing it can make you rethink your design and often leads to a better end product. And once you've done it, if you ever find yourself eating those words - as frequently happens - you won't have to worry about it. You're already set. Whereas otherwise you have a pile of refactoring to do and it's gonna be a pain.

Editted to clarify: I'm working on the assumption that this class is going to be spread relatively far and wide. If it's a tiny utility class used by one or two other classes in a single package then yeah, don't worry about it. If it's a class that's going to be used in multiple packages by multiple other classes then my previous answer applies.

Daniel Bingham
Following your advice, you'll have a huge pile of pointless interfaces and factories, and it's gonna be a pain. Tripling your class count just for the sake of "programming to an interface" *will* cost you dearly in maintenance.
Michael Borgwardt
@Michael Borgwardt: Yeah, I realized I was working on a possibly false assumption of class scale. Interfaces for *every* little class is bad. But interfaces for the more important ones that are going to be spread around is good - even if you think you'll only ever have one implementation. It's so easy to be proven wrong on that one it's not even funny - and refactoring isn't always easy.
Daniel Bingham
+1  A: 

Two somewhat conflicting answers to your question:

  1. You do not need to extract an interface from every single concrete class you construct, and
  2. Most Java programmers don't build as many interfaces as they should.

Most systems (even "throwaway code") evolve and change far past what their original design intended for them. Interfaces help them to grow flexibly by reducing coupling. In general, here are the warning signs that you ought to be coding to an interface:

  1. Do you even suspect that another concrete class might need the same interface (like, if you suspect your data access objects might need XML representation down the road -- something that I've experienced)?
  2. Do you suspect that your code might need to live on the other side of a Web Services layer?
  3. Does your code forms a service layer to some outside client?

If you can honestly answer "no" to all these questions, then an interface might be overkill. Might. But again, unforeseen consequences are the name of the game in programming.

rtperson
A: 

The question should be: "how can you ever be sure, that there is only going to ever be one concrete implementation?"

How can you be totally sure?

By the time you thought this through, you would already have created the interface and be on your way without assumptions that might turn out to be wrong.

With today's coding tools (like Resharper), it really doesn't take much time at all to create and maintain interfaces alongside your classes, whereas discovering that now you need an extra implementation and to replace all concrete references can take a long time and is no fun at all - believe me.

Thorsten Lorenz
+1  A: 

You need to decide what the programming interface is, by specifying the public functions. If you don't do a good job of that, the class would be difficult to use.

Therefore, if you decide later you need to create a formal interface, you should have the design ready to go.

So, you do need to design an interface, but you don't need to write it as an interface and then implement it.

David Thornley
A: 

A lot of this is taken from a Rainsberger talk on InfoQ: http://www.infoq.com/presentations/integration-tests-scam

There are 3 reasons to have a class:

  1. It holds some Value
  2. It helps Persist some entity
  3. It performs some Service

The majority of services should have interfaces. It creates a boundary, hides implementation, and you already have a second client; all of the tests that interact with that service.

Basically if you would ever want to Mock it out in a unit test it should have an interface.

Rob Spieldenner
+1  A: 

YAGNI - You Ain't Gonna Need It from Wikipedia

According to those who advocate the YAGNI approach, the temptation to write code that is not necessary at the moment, but might be in the future, has the following disadvantages:

* The time spent is taken from adding, testing or improving necessary functionality.
* The new features must be debugged, documented, and supported.
* Any new feature imposes constraints on what can be done in the future, so an unnecessary feature now may prevent implementing a necessary feature later.
* Until the feature is actually needed, it is difficult to fully define what it should do and to test it. If the new feature is not properly defined and tested, it may not work right, even if it eventually is needed.
* It leads to code bloat; the software becomes larger and more complicated.
* Unless there are specifications and some kind of revision control, the feature may not be known to programmers who could make use of it.
* Adding the new feature may suggest other new features. If these new features are implemented as well, this may result in a snowball effect towards creeping featurism.
Pedro Estrada
+1  A: 

I use a test driven approach to creating my code. This will often lead me to create interfaces where I want to supply a mock or dummy implementation as part of my test fixture.

I would not normally create any code unless it has some relevance to my tests, and since you cannot easily test an interface, only an implementation, that leads me to create interfaces if I need them when supplying dependencies for a test case.

I will also sometimes create interfaces when refactoring, to remove duplication or improve code readability.

You can always refactor your code to introduce an interface if you find out you need one later.

The only exception to this would be if I were designing an API for release to a third party - where the cost of making API changes is high. In this case I might try to predict the type of changes I might need to do in the future and work out ways of creating my API to minimise future incompatible changes.

flamingpenguin
+1  A: 

One thing which no one mentioned yet, is that sometimes it is necessary in order to avoid depenency issues. you can have the interface in a common project with few dependencies and the implementation in a separate project with lots of dependencies.

james