Best Practices in Software Development: Interface Overuse
“Program to interface, not to implementation” that is something that we hear through our career but I think we are not doing it correctly.
Join the DZone community and get the full member experience.
Join For Free“Program to interface, not to implementation” doesn't mean you should pair each and every one of your domain classes with a more or less identical interface. In doing so, you are violating YAGNI, and lowering the readability and maintainability of your codebase.
Extracting an interface from a class just so it has one, has this annoying feature that whenever you try to navigate using your IDE, you end up in the interface rather than the implementation itself. I see no practical use case in jumping to the signature declaration instead of the implementation itself. It’s annoying, a waste of time, a huge overkill, and completely useless, in general. What would you say to an experienced developer that adds an interface to a DTO class?!
Having one and only one class implementing an interface most of the time is an overuse of interfaces and it does more harm than good. We use interfaces in order to group together objects with similar behavior. However, when an object does not share similar behavior with any other objects, there is no need for this grouping; that object is already uniform by default.
People usually make excuses like “well, there might be new implementations for this interface in the future, so that’s why”. Which is a pretty bad one; there might not be new stuff to add as well. And even if such a new feature comes along, it’s enough to add the interfaces then — when you actually need them. Don’t fix what’s not broken; don’t add useless code trying to predict the future.
Agile Software Development Methodology
When a developer becomes familiar with Agile principles and values, a new world open up, and phases like the one below will have a different meaning.
There is nothing so wasteful as doing with great efficiency, that which should not be done at all.
Simplicity — the art of maximizing the amount of work not done — is essential.
Impl Is Meaningless
Naming a class with the Impl suffix is like saying, "I don’t know how to name it." If you can not find a simple name for your implementing class, it’s a sign of code smell. Things that can’t be named properly are either too complex or are doing too many things, thus usually breaking the Single Responsibility principle.
Please note that I’m not saying that interfaces are always bad. When they add value, they are useful. I’m only saying that interfaces that mirror one and only one class implementation are a waste.
Here are some cases where interfaces may be useful:
- When there is more than one implementation of a common interface.
- If you’re making a public module or library
Packaging by Domain
It is very likely that you are not using interfaces correctly if you are not structuring your project by domain. The clarity of having all the classes and files related to one domain under the same folder will help you avoid overusing interfaces, as you will only need to add an interface for you public class that acts as a facade to the package. This topic by itself deserves a new post.
Conclusion
Please make sure that you need the interfaces and layers of abstraction before creating them. I’ve come across many codebases that become very complex by trying to do things “the right way”.
The road to software development hell is paved with good intentions.
Published at DZone with permission of Alexsandro Souza. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments