Credits to the image: Dave Wolanski
Yesterday I was driving down the highway and it was very foggy. All along the highway, there were digital (variable) speed limit signs, which were showing a speed limit of 60km/h (instead of the default 130km/h) due to the bad road conditions.
And I thought to myself, how cool. The constructor of the highway decoupled the actual speed limit from the sign, just for cases like this. Now they have the flexibility to dynamically adjust the limit, based on the road condition. That was a very smart design choice!
The traditional solution would be to just place a metal sign, but this hardcodes the speed limit and cannot be easily changed (someone has to go to the sign, and place a new one in it's place, revert the change when conditions reset, etc.).
Does this mean all signs everywhere should be digital? Probably not. A digital sign can easily cost two orders of magnitude more than just a metal plate sign. And not to speak of the operating and maintenance cost.
Every abstraction comes with its cost.
The point of my post is to show that the same applies to software architecture. It would be great to have "digital signs" everywhere, decouple all of the things and have infinite flexibility. As much as it would be great to have a new Tesla with full equipment and all features unlocked. But do you have the budget to pay for the cost?
As much as we balance our budget when buying a new car, we as engineers should balance our budget for abstractions.
Knowing when and where in your product to invest in abstraction, like the digital road signs, and where to just place a metal hardcoded one can mean the difference between success and failure.
Where things need to change, invest in abstraction and layers. Where things are simple and static, go with the low cost solution. And if the simple thing starts getting complicated and changes frequently, THEN invest your budget in refactoring and abstraction. Your abstraction must provide more value than its cost, or else you are in trouble.
I would really like to hear your thoughts on this. How do you approach complexity and abstraction? Do you consider the cost of these abstractions?