17

There is a certain library I use in my project. This library has an interface which has about 15 methods.

The purpose of this interface is to make it possible to subscribe for some events that are generated in the library. A listener class in application can implement this interface and register itself as a listener in the library to receive events.

All the methods in this interface are actually events. There can be listeners who only need to receive only one or two events from many events in the interface. Even though a listener is only interested in few events, listener has to implement all the methods when extending the interface.

So I asked the developer of this library to add empty default implementations to the methods in the interface.

But the library developer refuses to add default implementations, stating that it would violate java best practices and using default implementations in interface methods go against the purpose of interfaces.

But, as I can understand, a method in this interface does not specify some action which an implementer of this interface should be capable of. A method in this interface rather defines an event which an implementer may be interested in. So I can't see a clear reason for not adding default implementations.

So, is adding default implementations to this interface break the java best practices?

psmears
  • 26,070
  • 4
  • 40
  • 48
Lahiru Chandima
  • 22,324
  • 22
  • 103
  • 179
  • You want an Interface with implementation? That wouldn't even compile. Unless I'm not understanding your question. – Manu Sep 07 '15 at 14:22
  • 2
    In java 8, you can specify a default implementation to interface methods, making it optional for an implementer of the interface to implement the method. – Lahiru Chandima Sep 07 '15 at 14:24
  • Didn't know that. It seems to me this feature is provided for backwards compatibility, while you should just use an abstract class instead of an interface. (You don't even need the library guy, just make it yourself) – Manu Sep 07 '15 at 14:29
  • The question might be: "Are there any widely adopted, precisely stated java best practices we can refer to?" – plastique Sep 07 '15 at 14:30
  • More precisely, "is there a java best practice which would prevent you from adding default implementations in this situation?" – Lahiru Chandima Sep 07 '15 at 14:38
  • 7
    This is really an opinion question; there isn't an objective answer. But remember that even if the library developer doesn't want to add default implementations to the interface, you can create an interface of your own that extends the one in the library and adds the empty default implementations. Your "real" implementation classes can implement *that*. – Wyzard Sep 07 '15 at 14:50
  • @Wyzard this is not an opinion question. Either the interface violates best practices or it does not. Asking _when_ it's appropriate to violate best practices would be an opinion question. – jaco0646 Sep 07 '15 at 15:54
  • 1
    @jaco0646 Okay, then please define "best practices" in a strictly non-subjective and non-arbitrary way. – biziclop Sep 07 '15 at 16:12
  • 1
    I would ask a different question though: why 15 methods on one interface and not 1 method on 15 interfaces? If there are valid listeners who only need to listen to 1 event, putting all 15 into one interface is the design flaw. – biziclop Sep 07 '15 at 16:14
  • 1
    @biziclop To your first point, do you imply that an objective question cannot be asked regarding best practices? To your second point, the relevant best practice is [Interface Segregation Principle](http://www.objectmentor.com/resources/articles/isp.pdf). – jaco0646 Sep 07 '15 at 16:40
  • 2
    In any case, it is clearly a fault of the API designer, and he needs to provide a better solution. – ZhongYu Sep 07 '15 at 17:06
  • 2
    It's comical that in computer industry people throw around big words and nobody knows what they mean. Why don't we stop speaking like some fundamental jihadists, and focus on practical matters, like, is there an easier way to user you API. – ZhongYu Sep 07 '15 at 17:12
  • @jaco0646 Yes, that's exactly what I'm saying. There's no such thing as a magical Best Practice that fits everything. There are techniques that work in most (but not all) situations and there are techniques that are almost always wrong (but sometimes unavoidable). So a good question for me is "does X work in situation Y?", these can be answered objectively. – biziclop Sep 07 '15 at 21:32
  • 3
    @biziclop I agree completely. A good question requires context, which this question does provide. – jaco0646 Sep 07 '15 at 22:03
  • @bayou.io [Best practice](https://en.wikipedia.org/wiki/Best_practice) is a term commonly used outside the computer industry. The assertion that nobody knows what big words mean seems to reflect more on the people than the words. And _easier_ is an even more subjective and arbitrary term than best practice. – jaco0646 Sep 07 '15 at 22:16
  • 1
    @jaco0646 I think the problem is twofold: first of all, there is no industry-wide agreement on many issues, so one person's best practice may be the thing to avoid for another. The second issue is using best practices as a blunt instrument to hit others with. "Because it's best practice" is never a valid justification for anything, best practices should always be backed by actual reasoning, rather than just appealing to an authority. This question is close to a good one, it's just worded in a way that may open a fruitless and subjective debate. Some would say it already has :) – biziclop Sep 08 '15 at 11:43
  • 1
    Relevant answer by a Java language architect: http://stackoverflow.com/a/28684917/1015678 – Lahiru Chandima Feb 21 '17 at 15:52

4 Answers4

8

But the library developer refuses to add default implementations, stating that it would violate java best practices and using default implementations in interface methods go against the purpose of interfaces.

This argument was valid until default interface methods were introduced. Now your colleague would have to argue that the JLS of Java 8 perverted interfaces and the JDK now contains classes which go against the purpose of interfaces. Still this is a viable extreme standpoint but fruitless.

You simply can avoid the discussion by deriving an own interface from the library interface and providing default empty implementations for all inherited methods.

public interface MyInterface extends LibraryInterface {
    @Override default public void event1() {
    }

    ...
}

Or you both can review the following design which seems dubious to me and which led to your discussion about default method in interfaces:

Even though a listener is only interested in few events, listener has to implement all the methods when extending the interface.

A solution could be to simply split up the big interface in many smaller ones.

wero
  • 32,544
  • 3
  • 59
  • 84
5

The library developer is wrong about this (I even dare to omit IMHO).

One of the reasons that many helper (both abstract and concrete) classes in Java have been introduced in the past is exactly the absence of features like default interface methods (for example the adapter classes in Swing which very much resemble the concerns you are asking about).

If not misused, multiple inheritance is desirable in some situations and, as we all know, by extending a 'helper' class in Java we are loosing the ability to inherit from anything else.

Actually, this is mentioned in the official Java tutorial, section "Abstract Classes Compared to Interfaces":

Consider using interfaces if any of these statements apply to your situation:

  • You expect that unrelated classes would implement your interface. For example, the interfaces Comparable and Cloneable are implemented by many unrelated classes.
  • You want to specify the behavior of a particular data type, but not concerned about who implements its behavior.
  • You want to take advantage of multiple inheritance of type.

The second and the third point are the perfect match for your use case I think.

Dragan Bozanovic
  • 23,102
  • 5
  • 43
  • 110
2

In short: Default methods should not be needed. The only reason they where introduced and are used within the JDK is to stay downwards compatible, and this should be the only reason to use it in your library. While default interface methods do NOT break the SOLID desin principles, there usage in your code are an indicator that you broke SOLID somewhere else.

In long:

I do not share the view of Dragan Bozanovic.

You want to specify the behavior of a particular data type, but not concerned about who implements its behavior.

This does IMHO not speak for interface default methods. Specifying behavior is not the same as implementing a behavior. And the second part of the sentence even says "you are not concerned about who implements the behavior". A default method would implement it by its own. It would be very much concerned about who implements it then. Still, you do not concern about who OVERRIDES it.

You want to take advantage of multiple inheritance of type.

Java knows about three inheritance mechanisms: Inheritance of state, inheritance of implementation and inheritance of type. All three of them are inheritance. This quote is talking about inheritance of type. Interfaces without default methods use inheritance of type. Defaults methods in interfaces are inherited by implementation.

I share the view of oracle

Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces.

The key part here is "ensure binary compatibility". I.e: It is bad design to use default for freshly created interface, but OKish to add them to legacy interface to not break the code of your clients.

With other words: Whenever you feel the need to use default methods you are probably breaking the SOLID principle somewhere in your architecture. Eg, the library you are talking about is breaking the Interface Segregation Principle.

user2542461
  • 49
  • 1
  • 1
  • 6
1

Since default methods enable us to add new functionalities to interfaces without breaking the classes that implement that interface so its definitely not a good practice because it combines the virtue of interfaces and abstract classes, but since that isn't an option I would strongly suggest that you provide your own skeletal implementation class, as this 'methodology' is used all over the Collections Framework in java, and that's just my humble opinion.

QuakeCore
  • 1,886
  • 2
  • 15
  • 33