Java Interfaces – Programming for Future Use

interfacesjavaobject-oriented-design

I have a colleague sitting next to me who designed an interface like this:

public interface IEventGetter {

    public List<FooType> getFooList(String fooName, Date start, Date end)
        throws Exception;
    ....

}

The problem is, right now, we are not using this "end" parameter anywhere in our code, it's just there because we might have to use it some time in the future.

We are trying to convince him it's a bad idea to put parameters into interfaces that are of no use right now, but he keeps on insisting that a lot of work will have to be done if we implement the use of "end" date some time later and have to adapt all the code then.

Now, my question is, are there any sources that are handling a topic like this of "respected" coding gurus that we can link him to?

Best Answer

Invite him to learn about YAGNI. The Rationale part of Wikipedia page may be particularly interesting here:

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 the 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 may preclude needed features from being added in the future.
  • 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 correctly, 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 could result in a snowball effect towards feature creep.

Other possible arguments:

  • “80% of the lifetime cost of a piece of software goes to maintenance”. Writing code just in time reduces the cost of the maintenance: one has to maintain less code, and can focus on the code actually needed.

  • Source code is written once, but read dozens of times. An additional argument, not used anywhere, would lead to time wasted understanding why is there an argument which is not needed. Given that this is an interface with several possible implementations makes things only more difficult.

  • Source code is expected to be self-documenting. The actual signature is misleading, since a reader would think that end affects either the result or the execution of the method.

  • Persons writing concrete implementations of this interface may not understand that the last argument shouldn't be used, which would lead to different approaches:

    1. I don't need end, so I'll simply ignore its value,

    2. I don't need end, so I'll throw an exception if it is not null,

    3. I don't need end, but will try to somehow use it,

    4. I'll write lots of code which might be used later when end will be needed.

But be aware that your colleague may be right.

All previous points are based on the fact that refactoring is easy, so adding an argument later won't require much effort. But this is an interface, and as an interface, it may be used by several teams contributing to other parts of your product. This means that changing an interface could be particularly painful, in which case, YAGNI doesn't really apply here.

The answer by h.j.k. gives a good solution: adding a method to an already used interface is not particularly hard, but in some cases, it has a substantial cost too:

  • Some frameworks don't support overloads. For example and if I remember well (correct me if I'm wrong), .NET's WCF doesn't support overloads.

  • If the interface has many concrete implementations, adding a method to the interface would require going through all the implementations and adding the method there too.

Related Topic