Today’s WTF? moment, found in some code I’m trying to sort out: (specific actual implementation hidden to protect the clueless)
private static void method(ItemInterface interface) { ItemImplementation impl; if (item instanceof ItemImplementation) { impl = (ItemImplementation)interface; } else { return; } some action on impl }
Here’s the thing. An interface provides an abstraction to hide the implementation, so you can swap implementations around without anyone being the wiser.
If you are “cracking the interface” by casting an interface reference to the underlying implementation, then why the fuck do you have an interface in the first place?
All it means is that you break the possibility of using an interface for what it is supposed to be used for, while preserving the illusion that you have some competence as a programmer.
Feh!
[Update: The code I was referring to was the client of a framework, where the client was casting the interface to the underlying framework implementation of the framework.]
There are some specific cases where such an implementation is necessary. Say that I have some industry specification that I need to implement. I have spec interfaces: InterfaceA, InterfaceB. I also have classes: ImplA, ImplB and method: InterfaceB.M(InterfaceA).
Now, let’s say there is some internal data structure of ImplA that ImplB.M needs to access. I can’t extend the interface to InterfaceA because that breaks the spec. One option I have is to add an interface with the method I need so that ImplA extends both InterfaceA and InterfaceC (my custom interface). If I don’t want the internal structure exposed to third-party developers through InterfaceC, I need to follow the second option: a cast of InterfaceA to ImplA, similar to the example that you give above.
The reason that this is not problematic is that if I am implementing the entire framework, there should never be a case where I don’t know the implementation(s) of the interface.
I don’t have enough info to judge the specific case that you cited. I would say that I couldn’t think of a case where this is needed if the developer has control over both the implementation and the API. The fact that the method returns if it is not the correct implementation, rather than throwing an exception, is suspect, however.
LikeLike
I dont know if mentioned use case was context specific, but I highly disagree with you on the conclusion in bolded font.
Lets say you have framework, and that framework has API interface named Message. Now clients use and program against your framework by using API, but since there are always some context specific things to take care of (such as transaction, session, uuid…) that framework must do internally but it must not allow client to alter the behaviour in any way, that is it is not visible to client. Of course client always can abuse it if he likes, but the idea is not to show him MessageImpl but rather only what is neccessary for him to do his job, Message.
LikeLike
Sorry; my article was use specific. In this case the code I was looking at was client code cracking the implementation of an interface of an object being constructed by a separate framework contained in a bean.
Worse, it was cracking the interface to get at the implementation of an object to invoke a method that, conceptually speaking, should have been declared as part of the interface.
I agree that within a well defined module of code (a framework, a bean) that defines the implementation of an interface, that module will need to be able to cast an interface into the object that defines the interface. This was a case where client code was cracking the interface into the underlying implementation–abusing the fact that the underlying implementation was declared ‘public’ for some other package of code internal to the framework.
LikeLike