3

My coworker and I are arguing very hard about this topic. He's thinking that every single class should have an Interface that the class implements (also Single-Implementations). He uses this design for documentation principles. In my mind that is obsolete because in Java you can comment on implementations, too.

I think that Interfaces are only needed there, where you have to publish some kind of open API, for yourself as the programmer, or for other people who later will connect their projects at this docking point.

Also I am in knowledge about Mocking Objects, whose library (e.g. EasyMock) also requires some Interface to create a Mock.

In my view, interfaces for every class are not necessary for every single class in JAVA. In other languages including some Frameworks it might be helpful.

Maybe you could show me some aspects that I don't see where Interfaces for every class might be helpful, or am I on the right way to deny this design principle?

DmiN
  • 161
  • 1
  • 5
  • 2
    possible duplicate of [What is the point of having every service class have an interface?](http://programmers.stackexchange.com/questions/150045/what-is-the-point-of-having-every-service-class-have-an-interface) and of [Do I need to use an interface when only one class will ever implement it?](http://programmers.stackexchange.com/questions/159813/do-i-need-to-use-an-interface-when-only-one-class-will-ever-implement-it) – gnat May 04 '13 at 21:01

5 Answers5

4

A unique interface for every class? By the great noodly appendages, that smells like an antipattern! Let's debunk a few things here…

Firstly, the only somewhat-valid reason for giving everything an interface is if you are very heavily using the built-in JRE proxy system (which can only construct proxies for interfaces). However, if you're doing that then you can also think in terms of using runtime class generation systems like the asm library to generate relevant proxies. (If you're getting deeply into that, look at how Spring and AspectJ work.)

Secondly, you should actually be thinking much more about grouping code into clearly defined APIs. Those APIs should be defined by interfaces (and relevant POJOs and exceptions as necessary) so that you think purely in terms of what that API actually promises and guarantees. Using the discipline of an OSGi bundle might well be a good idea here. That's also the level at which you really do your testing; that's the level at which you have black-box unit testing. Going within the implementation of the API — white-box testing — should be kept more to a minimum, because you're checking things in that case that should be unobservable to the outside world. (Creating lots of unobservable stuff is against the YAGNI principle.)

Of course, if you then keep the implementations thin so there is as little extra code other than the actual direct API implementation classes, that's probably a good thing under normal circumstances. Adding excessive amounts of abstraction does nothing except make you more confused!

Donal Fellows
  • 6,347
  • 25
  • 35
4

Oh dear, I don't know where to start...

You don't add an interface to a class. You implement an interface by coding a class.

Let's just say that I have come to appreciate coding against interfaces instead of classes for a multitude of reasons. High cohesion, low coupling design and testability being the most important.

Testability is greatly improved by using interfaces. Testability is also greatly improved by dependency inversion. And dependency inversion just happens to be so much simpler when using interfaces. (I am talking the principle here, not about frameworks, containers or libraries.)

Interfaces and dependency inversion allow you to create tailor made test stub classes for interfaces that the interface/class under test depends on, without having to worry about the parts of a "used" class that you do not rely on in the interface/class under test. (Please note that I do not use mocking. In Martin Fowler's words I am a classicist tester, using stub classes to isolate the class under test from external dependencies.)

So even when an interface will only ever have a single "real" implementation, it will soon have a couple of test stub implementations when it is used by at least one other class implementing another interface.

In fact, I nowadays code unit tests against interfaces and test an/every implementing class by registering a descendant class of the test class and setting it up to use the implementing class and any test stubs it may need. Thus ensuring that any and all implementations are tested against the same "contract".

Coding the tests against the interfaces also helps in focusing on the desired behavior and avoids being distracted by the implementation details of the class under test.

Marjan Venema
  • 8,151
  • 3
  • 32
  • 35
1

I think the first question to ask shall be what are interfaces about. Interfaces are contracts you expose to whoever uses your module, including yourself (in another module). They mark boundaries where implementation details can be not so important and can be exchanged without breaking contract. While classes are concrete details, and they implement the contract interface promised.

So if you follow this road, defining an interface for every class is definitely over moduled. Of course interfaces can also be used as a kind of tag, like "Serializable". But this kind of use is replaced by annotations after java 5.

TcMaster
  • 11
  • 1
0

As you allude to in your question, the big win of exposing classes only via interfaces is when you come to unit test, in particular automated testing.

If you test a particular class, and construct a particular interface through which the class is accessed, then not only will the class itself implement the interface, but any "mocking" component will also implement that interface.

Now having said all this, I've thought about this a fair bit myself, and I'm not sure it is something I'd buy into either!

PeteH
  • 276
  • 1
  • 5
0

On the floor of the truck I think you should make a more abstract question, for example, what should I expose in my API?.

After defining who really want to conquer the path gets easier.

About interfaces and classes, there is no rule that say 100% effective. Will depend somewhat the needs of your project.

Martijn Pieters
  • 14,499
  • 10
  • 57
  • 58
Wellington
  • 25
  • 2