0

It seems to be the standard so I have been going along with it so far, but now I am building a new class from scratch instead of modifying the old ones and feel I should understand why I should follow the projects convention.

Almost every class has an interface to it which is called classnameable. In the code database.class would never appear even once but in place where I would want to use that class I see databaseable.class.

To my understanding an interface was a class that was never implemented but was inhereted from to keep standards. So why are the interfaces being used as if they were real classes?

Skeith
  • 2,512
  • 5
  • 35
  • 57

4 Answers4

9

To my understanding an interface was a class that was never implemented but was inhereted from to keep standards. So why are the interfaces being used as if they were real classes.

This is a bit confused. An interface defines an API, so that pieces of code from different authors, modules or projects can interact. For example, java.util.Collections.sort() can sort anything that implements the List interface and contains objects that implement the Comparable interface - even though the implementation classes may not have existed yet when the sorting code was written!

Now the situation in your project seems to reflect an unfortunately rather common antipattern: having an interface for everything, mostly with a single implementation class, even for internal classes.

This used to be strongly promoted by proponents of Test-Driven-Development (TDD) who see it as vital to be able to test every class in isolation with all its dependencies replaced by mock objects. Older mocking frameworks could only mock interfaces, so to be able to test every class in isolation, all inter-class dependencies had to be through interfaces.

Fortunately, newer mocking frameworks can mock concrete classes and don't require you to pollute your project with unnecessary interfaces. Some people will probably still argue that it should be done anyway to "reduce coupling", but IMO they're just rationalizing their desire not to change their practices.

And of course, if you don't do fundamentalist TDD, there never was a good reason to have an interface for everything - but very good reasons to have interfaces for some things.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • so would you say i should create an interface for the class i am writing to stay comparable even it does not need it – Skeith Aug 10 '11 at 11:44
  • @Skeith if your class should be comparable it would have to implement the `Comparable` interface - if it doesn't need to be comparable, you don't implement it. In neither case do you need to create your own interface. - As Michael said, you use an interface to define which methods a concrete class must have to be used in some code IF you don't know the implementation yet or have multiple implementations. To extend the example: `Comparable` was introduced in order not to write a `sort()` method for `Integer`, `Long`, `String` etc. but only one, since they all implement `Comparable`. – Thomas Aug 10 '11 at 11:49
  • @Skeit: That's a bit of a difficult question. Personally, I would not perpetuate such bad design just for the sake of consistency, but others might disagree. Of course, if the reason was the use of an older mocking framework, you'd also have to update it or introduce a second one to test your new classes, which might be a bit much for someone new to the language and the project. – Michael Borgwardt Aug 10 '11 at 11:51
  • @Thomas: I suspect Skeith meant "consistent" rather than "comparable". – Michael Borgwardt Aug 10 '11 at 11:52
  • What has me really confused is that the project was done only 2 years ago and there is no unit testing so I don't think TDD was used :( – Skeith Aug 10 '11 at 11:53
  • @Thomas sorry I did not realise comparable was a reserve word, I just meant to follow the pattern of the other classes. – Skeith Aug 10 '11 at 11:54
  • @Michael that makes sense. I'd also agree that interfaces shouldn't be introduced just for having them. If they're not needed, throw them away (or at least don't add new ones :) ). – Thomas Aug 10 '11 at 11:55
  • is it possible that all the interfaces are causing the general speed issues i am seeing ? – Skeith Aug 10 '11 at 12:04
  • @Skeith: in that case it might just have been a case of cargo cult design (following a rule without understanding why). Another possibility is that the original developer came from a C++ background where every class has its method signatures listed in a separate header file, and wanted to have the same pattern in Java. In any case, it's not a good design. – Michael Borgwardt Aug 10 '11 at 12:06
  • @Skeith: It's very unlikely to cause performance problems; calling methods through interfaces is a bit slower, but not noticeably so on a modern JVM. – Michael Borgwardt Aug 10 '11 at 12:07
2

If you've got an interface for pretty much every single class in your project even though there's no reason for it, that's not a good thing and in this day and age there's no great reason for it. It may be a legacy from days gone by when it was required by some external testing toolkit for instance - but these days that's not a requirement.

It may be of course that someone's heard that loose coupling is a good thing, that you should always couple to interfaces and not concrete classes, and taken this idea to an extreme.

On the other hand, it is good practice to define interfaces for some classes even if there's only one of them (at the moment.) When I'm writing a class I try to think along the lines of whether another (potentially useful) implementation could exist, and if so I'll put an interface in. If it's not used it's no problem, but if it is it saves time and hassle and refactoring later.

Michael Berry
  • 70,193
  • 21
  • 157
  • 216
1

If you want a class for your interfaces then a common way is to create an AbstractFoo class to go with the Foo interface. You can provide simple implementation of the required methods, allowing derived classes to overwrite them as needed. See AbstractCollection for an example of such a class.

The advantage is that you don't have to implement all the small stuff, it is already done for you. The disadvantage is that you can't inherit from any other class. You pays your money and you takes your choice.

rossum
  • 15,344
  • 1
  • 24
  • 38
1

A good indication for bad design is when you have a ISomething or a SomethingImpl. The interface name should state how to use it (i.e. List), the class name should state how it works (i.e. ArrayList).

If you need pre- or suffixes because the names would be the same, this means there is only one way to implement it, and then there is probably no need for a separation. (If you think there will be more sophisticated implementations in the future, name your class DefaultSomething or SimpleSomething)

Cephalopod
  • 14,632
  • 7
  • 51
  • 70