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 ;-).