While it is likely this post can stir some controversy, among my friends who are more "purist of design rules", I think a dicussion is well worth.
I was searching totally unrelated information, when I hit the web site of my long time friend Bruce Eckel (of Thinking in Java and Thinking in C++ fame) and read this very interesting blog post:
Unspoken Assumptions Underlying OO Design Maxims
In the post Bruce refers to and comment this blog post by Julia @coding:
Flexible code considered harmful
Both are quite interesting, even if I don't agree in full I think they have a point. It is true developer very often over-architect their code in light of future extensions, resuming they know how the requirements will change and how they'll be able to extend the software because of their nice architecture. But how often this is true compared the times the software is never extended into that direction -- but in a different one -- and the over-architecture becomes immediately a cumbersome technical debt making negatively affecting other changes required (but unexpected)?
From Julia's blog, I find this provocative but honestly quite relevant:
"Keep in mind that speed is achieved by writing simple and direct code with as few abstractions as possible."
This is a thing I countered to the "RAD = bad design" crowd out there. I think this particularly applies to some over-designed JavaScript libraries out there, even though I'm far from an expert in the JavaScript world. Not don't take me wrong, it totally depends on the task at hand, the size of the application, and the requirements you are starting from. Honestly, it is another way of stating the KISS principle: Keep It Simple, Stupid!
Now, considering Bruce blog post he underlines some unspoken assumptions we have as developers (and software architects):
- "We somehow know how a system will change"
- "Abstractions are always worth their cost"
We need to question these assumption, and consider if they apply to the task at hand. It is not they are always false, but also they are not always true.
What I found particularly interesting is his comment about "programming against interfaces" and how this rule got morphed from "interface" as a concept to "interface" as a keyword. He refers to Java, but I've seen that applied to Delphi quite often. Now it is undeniable that an interface (in the language) offers much looser coupling than a class "interface" (the collection of public methods and properties) or a unit "interface" (type and symbols exposed by a unit and declared in the interface section), but all three scenarios account for "programming against an interface" in the original terms of the concept.
Am I saying you should not use interfaces? Absolutely not, it is a great language feature and helps reduce coupling and creating better and more flexible systems. What I'm saying is that the interface keyword should not be the only abstraction you code against in a Delphi application.
I really like the final recommendation by Bruce Eckel, which I'll rephrase as: If you can only justify an abstraction by #34ing a maxim, take it out!
Happy coding ;-)