Call it software architecture, call it software design or call it programming motherf••ker: Interfaces are everywhere, be it your method signature on an API level, be it your RESTful service on a microservice’s level or be it your command line arguments of your shell script. So why is everybody talking about code review but nobody on interface review? Go away code review, I want good interfaces!
To make it clear right in the beginning: There are no unbreakable interfaces, there are far too many factors influencing the direction an interface is evolving.
While discussing whether a foreach loop
might be better than an iterator
or why a functional approach is now the only way to go, it seems to me that many software developers consider interfaces to be an unavoidable side effect of coding.
Coding dojos are organized and code reviews are held in order to get better code. But who needs better code when nobody can intuitively use the exposed interface and when the interface breaks the moment the functionality needs to be adjusted or a back end changes?
Did you ever ask yourself the question on who is using your interfaces versus on who is having to debug your code? He? Simply speaking, many programmers are using your interfaces, most probably just you is debugging your code…
Usually you have a
many-to-one
relationship between consumers of your code (via your code’s interfaces) and you, being the code provider.
Code versus interface
Consider the two situations we can run into, focusing on good code versus focusing on good interfaces:
“You coded some great code” versus “You defined a great interfaces”:
You coded some great code
Like a coding hero you put all the known best practices into your code, you welcome the dos and you avoid the don’ts. All those coding dojos made you great. You will be the first one who wins this battle on coding versus interfaces as your code will be up and running while the interface is still in the design phase.
There was that interface to your great code, it came out of nowhere as you were coding along that great algorithm. The code reviewer was very pleased, as you used all the great features which your programming language provides on the control flow level. Tackling the unit tests feels clumsy as you have to add some hacks to your code getting it testable, especially those edge cases … it’s not your fault, that code’s interface just came out of nowhere?
Then you check-in your code into the version control system (VCS
) of your choice. Most probably it’s a GIT
repository, because you consider that a good coder’s code to be even better when it uses the most hyped tools. Now someone has to operate on your great code, your interface is being invoked from code outside your direct scope.
As time goes by, more and more such interface consumers attach to your code through your interface. We have many(!) consumers of your interface and one(!) coder of your code (you).
Now the company exchanges a back end and, oh my god, your great algorithm relies on the technical details and the control flow of that back end …
Or consider the business domain changes and your algorithm’s return value cannot cope with this change? Your interface breaks immediately.
Guess what? All your clients consuming your interface will break now as well!
You think you are clever and put yet another implementation next to the old one providing the new and real implementation, keeping your broken implementation as of compatibility reasons, hacking it to get it somehow do something useful. Either way, sooner or later all your clients are broken as well, having to switch to your new implementation. But your code, it was so great…?
You most probably will end up with hacks giving your code a bad code smell for the sake of not breaking any interface consumers (at least for now).
In the end though all the clients using your interface have to touch their code and you have to touch your code. As it is a many-to-one
relationship between the consumers of your interface and your interface, many + one parts of the overall code have to be refactored.
You defined a great interface
Like a criminal profiler you creep into the heads of your interface’s potential consumers, those coders who will use your code. Like a criminal profiler you creep into the heads of those product managers defining your algorithm’s business domain. Like a criminal profiler you virtually feel what them coders will expect or will do wrong and what can go wrong when they use your code. Like a criminal profiler you virtually feel what that product manager is up to and what this product manager will be up to in the near future.
You understand what is and what will be required from a technical and from a business domain’s point of view. You spent some time on thinking about that interface, but now as you have it, its just writing down lines of code to get it implemented - piece of cake. Coding is just busywork when having a sound software design. The coding hero is not much in advance anymore…
Your code might be crappy, but you took care that the bunch of unit tests put around your code’s interface all of them pass!
Now the company exchanges a back end and, oh my god, your crappy code is affected! Fortunately you have a good interface in front of your crappy code, technical details and the control-flow of that back end are hidden by your interface.
Or consider the business domain changes and your algorithm’s return value cannot cope with this change? Fortunately you just have to extend the result returned by your well thought out interface and just adjust your crappy code to take this change into account, but your interface does not break!
Good news, none of your clients consuming your interface will break neither!
In the end no client using your interface has to touch its code and just you have to touch your code. Even though it is a many-to-one
relationship between the consumers of your interface and your interface, just one part of the overall code has to be refactored.
No more code reviews please!
Those two examples represent two possible extremes when talking about code and interfaces. I wrote this to emphasize that from my subjective point of view, focusing on interface design is much more important than focusing on great code.
I want interface reviews! I want consistent and intuitive interfaces. I want interfaces which hide away specific technical details behind. I don’t want to care about which style or programming language resides behind that interface!
Actually, the code behind your interface has a real chance to get mature when your software design is sound and the interface is stable!
Links
See also Yet another REST cheat sheet on how to formalize the design of your RESTful
service.