Last week I gave another training. The group consisted of mostly fresh developers. One of the characteristics of such developers, is misunderstanding the Interface concept. When I say "interface" I'm referring to Java interfaces (interfaces were not part of the original OOP concept). In my opinion, understanding and using interfaces correctly is a positive sign of a mature and experienced enterprise developer.
Interfaces are the path which leads to the decoupling heaven. A developer working on his/her own or in a very small team cannot fully comprehend the importance of true decoupling of components. For me, I think it was COM which made the difference. COM, Microsoft's Component Object Model, defines a platform and a protocol for connecting binary components. Binding binary components means that the components are compiled to a binary form, hence, can be written in virtually any language. The icon representing an object (or component) in COM was a box with "handles" which represent the interface. An object can only be handled by the interface.
Obviously, this is not the case in Java. Java allows the tight coupling of objects. This leaves the responsibility to the developer.
Three thumb rules to achieve implementation independence:
- Return interfaces from your methods - do not return an actual implementation. This is especially important when dealing with public methods.
- When casting - cast to an interface rather than an implementation.
- All public methods should be defined in an interface. All other "implementation" methods should be kept private or protected.
This can bring you to the decoupling utopia... but it can also drive you crazy. Because:
- You will need to write and manage more code.
- Program structure becomes more complex.
- It's difficult to trace the program execution path when statically browsing the code.
The last point is a tough one. Modern IDEs can easily show you a "Call Hierarchy" view or simply jump to the method body. However, when working with interfaces this feature is disabled, since the execution refers to the interface and not the implementation. Here's an example of a Call Hierarchy view from Eclipse:
The solution is probably in a middle way. The developer needs to decide where it is necessary to decouple and where this is just a waste of time. It is difficult to give a well defined set of rules for the decision, hence, different people in the same team may come to different conclusions.
Final note: if the tools were good enough to work with interfaces intuitively, would you be using them to their full extent? I know I would.