Take the 2-minute tour ×

This question already has an answer here:

At the company I work at, every service class has a corresponding interface. Is this necessarily? Most of these interfaces are only used by a single class and we are not creating any sort of public API. With modern mocking libraries able to mock concrete classes and IDEs able to extract an interface from a class with two or so clicks, is this just a holdover from earlier times?

share|improve this question
Maybe they were produced from some code generating tool? –  FrustratedWithFormsDesigner May 24 '12 at 15:59
Whenever I see case like you describe, I expect there to be a doc / comment to justify it, or, better yet, a unit test that demonstrates the need. When there's no such stuff, well I think that's a serious problem –  gnat May 24 '12 at 16:16
@gnat - that no more demonstrates the necessity of the design choice than testing that a class implements a "foo" function demonstrates the necessity of that function being called "foo". By writing the tests you describe you're checking that a certain protocol is being implemented, not that this protocol was needed. If, as the OP claims, you could just as easily write the program without the interface your tests would be just as valid or invalid depending only upon the choices made by the architect. –  Crazy Eddie May 24 '12 at 17:17
@gnat - again then, how do you demonstrate the need to have an interface between two classes rather than coupling them directly? I simply don't see how just checking that a class does implement an interface demonstrates the need for that abstraction. You've claimed that there should be a unit test demonstrating the need for it first. You've yet to make any sense of that claim. –  Crazy Eddie May 24 '12 at 18:37
What is a "service class"? –  user1249 May 24 '12 at 21:28
show 9 more comments

marked as duplicate by gnat, Joris Timmermans, Kilian Foth, BЈовић, Jalayn May 17 '13 at 14:18


6 Answers

Your company is following the SOLID principles and targeting an interface rather than concrete class adds zero overhead to the program. What they're doing is a very moderate amount of extra work that can pay back volumes when the assumptions that you are making end up being false...and you can never tell what assumption that's going to be. What you're recommending while slightly less work, can cost many, many, many hours of refactoring that could have just been done ahead of time by simply following basic OO design principles.

You should be learning from these guys and consider yourself lucky. Wish I worked in such an environment where solid design was a priority goal.

share|improve this answer
Just because there's no seeming utility today doesn't mean it has no utility. –  DaveE May 24 '12 at 18:21
There may be utility already. I don't know if they're doing so, but a single implementation can fulfill many interfaces. If the interfaces are minimized to the least needed functionality for a given kind of client then this enables the code to explain those clients without having to understand a larger interface that's not being entirely used. It can also discourage cross-concept invasion where a client meant to work with the object in one way begins using functionality it shouldn't. A view beginning to use a model's mutable interface for example...probably shouldn't be. –  Crazy Eddie May 24 '12 at 18:34
@CrazyEddie nope, the interfaces are used one-to-one like com.company.service.foo and com.company.service.foo.impl –  Bob Roberts May 24 '12 at 22:48
@DaveE: YAGNI says you're wrong. –  DeadMG May 26 '12 at 16:10
Whenever I see SOLID used as a reason I cannot help but think there is no justification at all for the design. For surely if there was the respondant would give a more specific reason. –  Jonathan Allen Sep 4 '12 at 6:48
show 2 more comments

Given your question I assume that the reasons for this kind design are not documented.

Unjustified usage of an interface with single implementation is plain wrong since this violates YAGNI. In my experience, this also has been pretty damaging maintenance-wise, mostly because methods implementing interface are forced to be unnecessarily public. After you gather more refactoring experience, you'll probably learn to appreciate modest charm of private and package private access modifiers allowing one to focus attention within a single class / package.

As for undocumented justified usage of this idiom, it is in my eyes about as bad - first of all because it doesn't allow a maintainer to "tell good from bad". As a result, this leaves one between not quite appealing options. Options are, either you keep the questionable public stuff as-is, thus repeatedly decreasing productivity every time you need to change the code, or you make risky changes by blindly "collapsing" the single-implementation into easier to maintain POJO - exposing self to the risk to painfully discover that this is wrong way, that some other (God forbid, remote) module out of your sight expects the interface.

I've been through "revelations" caused by erroneous collapse of single-implementation-interface few times. Each time it has been quite an educative experience but I would not really want to get there again. Thing is, this happens at late testing, at integration or even at user acceptance and rolling back / fixing the mistake made long time ago at this stage is quite cumbersome.

  • An option that shouldn't be left without mentioning is to investigate whether the undocumented use is justified (and, after that, collapse or document respectively) right at the moment you find it.
    To me, this one has been quite counter-productive. This approach essentially forces one to go full-round integration testing which is probably one of the most efficient ways to break a flow in the middle of some complicated fix / refactoring.

I just couldn't see the practicality... the interfaces are used one-to-one like com.company.service.foo and com.company.service.foo.impl

Well below is about how I typically handle cases like that.

  1. Create a ticket in issue tracker, like "PRJ-123 Undocumented questionable use of interface with single implementation in Foo / FooImpl".
    Add to ticket description or to comment an explanation that this hurts maintainability and point out that without documentation this looks like overengineering. Add a comment suggesting to fix the issue by "collapsing" this into a POJO, for easier maintainability.
  2. Wait for some time just in case if someone comes to explain things. I'd wait a week or two at least

    • If someone explains the purpose, a) put that to the ticket, b) add to Foo javadocs something like purpose of interface explained in ticket PRJ-123, c) close the ticket, d) skip next three steps.
    • Otherwise, ...
  3. Come to team lead or manager to ask what would they think if I fix the ticket as suggested.
    Pick an adviser having sufficient authority to stand the "scream test" in case if suggested fix turns out wrong.
  4. Collapse to POJO as per suggested fix, arrange code review if that's possible (in slippery cases like that it won't hurt to cover your back).
  5. Wait until the change passes the full testing and update the ticket depending on its outcome - add the information on whether the change passed testing or not.
  6. Create and handle a new issue tracker ticket to deal with remaining similar cases based on the outcome of your pilot ticket (PRJ-123): either document the purpose, or collapse to POJO.

share|improve this answer
It is true that methods are forced to be public, but interfaces themselves can be public, protected, package private, or private. I could imagine creating a private interface (nested inside another class) that is implemented by 2 or more classes (also nested inside the same other class). If you are only going to have 1 implementation class, why bother. But a private interface would escape the productivity trap you described. –  emory May 24 '12 at 23:59
@emory great minds think alike; I am quite huge fan of private / package private interfaces. One thing that makes these particularly great is that one can figure their purpose looking only within class / package –  gnat May 25 '12 at 8:28
YAGNI is not universally accepted as a valid principle, even in combination with the supporting practices –  Oscar Mar 12 '13 at 16:52
add comment

Java interfaces aren't just about mockability (though of course, that is a factor). An interface exposes a public contract for your service, without implementation details such as private methods or attributes.

Note that "public" when using internal services (as in your case) refers to the actual users of said services, including -- but not limited to -- other programmers and internal services!

share|improve this answer
The answer is really no more complex than this. Interfaces represent a contract and enable dependency injection and mocking without the excessive and inefficient use of reflection that many frameworks provide for class injection and mocking. –  maple_shaft May 25 '12 at 2:16
The public keyword does an excellent job at exposing a public contract for my classes. –  Jonathan Allen Sep 4 '12 at 6:50
@JonathanAllen It still leaves you with non-public clutter. And what if your class implements two different interfaces? In Java, interfaces look like the cleanest way of communicating public contracts. –  Andres F. Sep 4 '12 at 12:38
In Java, abstract interfaces are better than public interfaces because you have already decided to use two of them? That's not much of an argument. Nor does adding "extends foo" do anything to remove "non-public clutter". –  Jonathan Allen Sep 4 '12 at 18:31
@JonathanAllen First, all interfaces are abstract in Java :) Second, you're looking at the wrong end: it's not from the implementation where you must remove the clutter, but from the interface itself (i.e. from the "contract"). The implementation is not the contract, the interface is. You aim to keep this contract "uncluttered". It's harder to do this with classes, because you also have your "non contract" methods (private, in your example) which aren't part of the public contract. –  Andres F. Sep 4 '12 at 20:29
show 2 more comments

One possible reason for every service class to have an interface is that it makes interactions with sophisticated frameworks (e.g., Spring, JEE) much simpler. This is because Java can simply generate interceptor objects against interfaces (see java.lang.reflect.Proxy); doing so against concrete classes is far more tricky and filled with some non-obvious caveats when working with multiple different classloaders. This holds doubly true if you work with OSGi, where those service interfaces will end up being loaded from a different classloader from the implementations of those services. That (together with the service discovery fabric) in turn enforces very strong separation between each service and its clients; the clients literally can't break the abstraction.

Be aware that even if an IDE can extract an interface from a class with a single click, it doesn't mean that it's necessarily going to extract the correct interface. Intelligence is still needed.

share|improve this answer
I'm not so sure 'sophisticated' is the right word. I think clumsy is more accurate. But if you have already decided to use one of them, then there is nothing to debate. Abstract interfaces must be used. –  Jonathan Allen Sep 4 '12 at 18:32
add comment

Here is how Adam Bien think about this question: Service s = new ServiceImpl() - Why You Are Doing That?

That is not only bloat (and the opposite of "Convention Over Configuration" idea), but it causes real damage:

  1. Imagine you get another implementation (thats the whole point of an interface) - how would you name it?
  2. It doubles the amount of artifacts - and significantly increases the "complexity"
  3. It is really funny to read the javadocs on the interface and the impl - another redundancy
  4. The navigation in the IDE is less fluent

and I agree with him.

Maybe your co-workers are still stuck in time with J2EE, because this was necessary when working with J2EE, maybe you can find on the internet old tutorials about hard times in J2EE.

share|improve this answer
add comment

It seems like overhead to use Interface initially.. but later on when we need to extend some functionality these Interfaces help a lot.

If you do only concrete implementation you have to change code implementation a lot.. But by using interface you just need to add one new class which implement the contract of Interface (and you can call new class object from the reference variable of Old interface).

share|improve this answer
You are talking in circles. To make your case you need a concrete example. –  Jonathan Allen Sep 4 '12 at 6:51
add comment
