Optional interface methods – curse or blessing?

As already explained in my last post, some stuff I stumble upon puts my brain in some kind of “continous elaboration” mode I can hardly fight against. A few days ago I clicked on a question at codekicker.de dealing with “interfaces” in Objective-C. Since I don’t have any clue on Objective-C (other than knowing that I don’t want to learn it) it was quite interesting to find out that this language indeed supports interfaces as I am familiar with (from e.g. Java or C#). From the given answers I learned, that the equivalent in Objective-C is a protocol. Codekicker member puls200 pointed out that, nevertheless, there is a difference between an Objective-C protocol and an e.g. Java/C# interface:

Objective-C allows to tag an interface method @optional

Take a minute and think about that for yourself… an optional interface method

As the title of this post already asks, what is your opinion on optional interface methods? Do you regard it a curse or a blessing? I would be happy if you post your opinion in a comment.

As far as I am concerned I see no practical benefit of one or more optional methods in an interface. I go a little further, I would ban its use by coding convention. I started some research on the web and discovered a post at chaoticjava.com that dealt with the same topic: The @optional interface method.

I put a link to this post here because it sums up a lot of arguments pro optional I discovered over and over again during my web research. Reading that post (if you haven’t already done it, here is the link again) will give you a good idea of the most common reasons pro optional.

The author of that post was thinking of cases where indeed optional interface methods would be useful. Although I like the idea of using an annotation processor or some kind of aspect framework to enrich an @optional annotation with metadata further describing how to deal with a defined option down at single method level, it is the fact that (in my opinion) an interface degenerates from a contract to a wish list.

Things get worse when a single interface contains more than one optional method. Is any possible combination of mandatory and optional methods valid, ie. does the implementation of one optional method demand implementation of another one (or two) methods? I am not willing to pay the price of such complexity and confusion only to save on a few lines of (admittedly) boilerplate code. Boilerplate code is boring to write and read, but it is normally well understood (otherwise it would not have been assigned the attributes boring and boilerplate, would it?). It may also be error-prone when handcrafted, but I dare to claim it is easier to test than all possible method combinations in all relevant contexts.

The worst thing about all this is, that it seems to be quietly agreed upon that everyone is free to decide whether to implement a given interface method or not. The common justification is that the frameworks do this as well. Provocative: “if a method is not handy in a certain case, a kind of “not supported exception” may be thrown and everything is ok”. Have you ever heard of the broken window theory? Do you want to be a blindfolded framework lemming?

When reflecting the need for optional interface methods with respect to clean code developer principles, I find quite a few principles that are violated in my understanding of these principles:

  • interface segregation principle. When I think of making an interface method optional, I am possibly (with a strong tendency towards 100%) mixing things up that don’t belong together.
  • principle of least astonishment. When I call an interface method I am (hopefully) prepared for catching documented domain exceptions (or better: I am able to verify all preconditions of a method before calling it, so I can minimize exception handling), but honestly, a NotSupportedException is not what I’m expecting.
  • single responsibility principle. Optional methods increase the danger of “reusing” an interface by adding optional methods that are needed only in certain special cases, since it does not break the original implementations.
  • tell, don’t ask. If an interface has optional methods, a caller would¬†always have to ask for the existence of an optional method for a given implementation before calling it, or catching a NotSupportedException to find out. The caller is then forced to make decisions based on the existence of an optional method, leading to call site contamination scattered all around. A possible and obviously very simple solution is to implement a derived interface, so using the derived type tells what its capabilities are. No need for further asking.

I could probably continue this list with a few other principles, that may be violated in certain cases only. But I think the list above is enough, it shows my point of view. Now it’s up to you…

Why would you regard an optional interface method useful? Or why do you avoid it? I would really appreciate if you leave a comment pointing out your opinion on this topic. And by the way: thanks for reading to the end ;-).

3 thoughts on “Optional interface methods – curse or blessing?

  1. If every optional interface method has a default implementation this concept can be very useful. In .NET, abstract base classes already have this feature. You can put virtual methods in them.

    Also virtual methods/optional interface members help with versioning.

    1. Hi Marvin, thanks for your feedback.
      I agree, versioning is indeed an issue where optional methods might be helpful. Although versioning problems can be solved with other techniques, optional methods would be handy in this case.
      If you think of abstract classes and virtual methods, you are right. But only then I am able to control each optional method very fine grained, deciding for each default implementation. If I come across a method where I would throw a NotSupportedException, I leave it abstract instead. So using abstract classes for providing some default implementation and leaving some other optional is perfectly fine. That is exactly what I think is one of the alternatives to optional interface methods where the code clearly communicates its intentions.
      As well as introducing new interfaces (instead of adding optional memebers): I can inherit from an existing interface and add the optional methods to this new interface, so I have a new type. When using this new type I can be sure, that it supports the functionality I expect.
      Thanks for your opinion on this, Marvin.

  2. If there is a need of implementing a method by using a NotSupportedException there is something wrong with the corresponding interface. Either my class which implements the interface does not fit to the interface or the interface design is wrong. It’s dangerous to implement the interface’s contract only half-finished. I totally agree to your argument that optional interface methods violate several clean code principles.

    If my software design should support optional features, i have to be able to ask if a concrete component supports a feature or not (there are already proven patterns for this behavior!). Otherwise the only possibility to check if a feature is available is to catch the NotSupportedException – and that’s no good coding style.

    Furthermore i think such optional interface methods are not compatible with the Design by Contract principle. We perceive an interface as a contract between caller and consumer. In our business world it would be unimaginable that one party does not keep with a contract. Why it should be possible in a software architecture to support only a subset of the contract’s conditions? Isn’t it better to separate such features in different interfaces? I don’t know how to define a contract which says “well, this feature can be implemented by consumers, but it can also crash at runtime”. Ugh!

Leave a Reply

Your email address will not be published. Required fields are marked *