Optional interface methods – good or evil?
Just kidding, read on.
I’m very open to major improvements to the ABAP language, mainly because a lot of them allow creating cleaner code – more compact, self-describing and less “crowded” with declarations. But this weapon is two-sided and used improperly can actually do the opposite – armed in expression-style statements you can easily achieve unreadable code, too concise in places where it should be delivering some meaningful information for the people reading it. Some of the language improvements can also introduce more subtle possibilities to do the bad things and one of such features is optional interface method (https://blogs.sap.com/2014/10/10/abap-news-for-740-sp08-optional-interface-methods/).
Before let’s quickly recap what are optional interface methods. Based on my internet activity I can assume that it is not so sexy feature like other changes in the ABAP language introduced in recent years.
Basically, it allows declaring an interface method as optional and setting how to react to calling such method when it is not implemented:
– IGNORE – the behavior is the same as calling a method implemented with an empty body
– FAIL – CX_SY_DYN_CALL_ILLEGAL_METHOD exception is thrown, if not handled => CALL_METHOD_NOT_IMPLEMENTED runtime exception.
The ease of (over)use
If you have reached this feature and its documentation, then probably you know that it’s not an option for a daily basis usage. But still I see a potential group of developers, who might be thinking how to bring it to their lives. The thing is that armed with such possibility it’s much easier to use them in place of proper interface segregation and break ISP and/or LSP rules from the SOLID principles. You can just add some method to the interface with an IGNORE flag, just for the case if some clients will not need it. Maybe you feel that it should be designed in a better way, but under the stress of time and other factors you skip it – “I will refactor this later”.
Maybe you don’t see anything wrong with making half of your 20 methods optional – “hey, I’m not sure but I put these methods here, just implement what you want and don’t bother about the rest!”. Well, this is a hard case…
Why it’s important, at least for me, to keep the interfaces as strict as possible? Because object-oriented design is about behavior. You rely on the behavior offered to you by an interface and delivered by the object implementing the interface. You expect the behavior when you call a method – not a “silent revoke” of your request to fulfill a contract. Mentioned SOLID principles help you to keep the code clean, reasonable and reliable. Using interfaces should be “0-1”, whether it offers some functionality or not, not “maybe” – it makes the design more straightforward. With the second option (an interface method marked with FAIL) you can at least react to the exception and provide additional logic if the method is not implemented.
OK, that’s my ideal world, now let’s come down to earth.
There might be situations, that using optional method is the last option to use. The JDK 8 and similar concept of default interface methods is a good example – introduced to bring lambdas to the Java Collections API, they extend core interfaces without breaking existing implementations. Sometimes you might need such last resort to make changes in your production-released frameworks. You might also use it for the classic Composite design pattern with transparent methods for leaves & composites – less empty methods in your code.
In my opinion, for the majority of cases, optional interface methods should be the last option, especially in the design phase. I rather treat it as an emergency fuse.
So it’s good or evil?
Well, for me it’s a good thing that such mechanism was introduced. It’s always better to have more possibilities offered by a programming language; it’s up to you how you use it.