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?
Reading/listening material:
Top comments (7)
Great tip Marko. In fact, I believe we can apply Pareto's principle in architecture too.
Providing an abstract layer for the 20% of things that will change more frequently is often good enough for a medium-sized project.
I'd say it's also difficult to abstract in advance. Most of the times you have a bunch of requirements and you try to fit them in a "generic context", just to figure out they don't any more a couple of months later (when they drastically change).
It's up to the developer to understand what needs to be abstracted (most common patterns like auth, routing, caching and stuff like that) and what may be left for a future refactoring (specific data or processes that are subject to change and not fit anymore).
What do you think, did you have any similar experience?
Hi Giovanni, what an absolutely brilliant response! I agree 100%
Lovely comparison!
After dishes, now we have a road signs 😄
I would suggest adding a few tags to your post, so it could get a better reach :)
Thanks! The post is really abstract (pun intended), I don't know what category/tag does it fit. What would you suggest?
It's hard to find something "super niche" for this one, but I think that #programming, #webdev and #architecture are a good start.
Be aware that time is also important. Usage of the suggested tags might have given better results if they were added at the time of publishing. Because when you display posts for specific tag, the new ones will appear, but not for long, if they don't catch attention. Also, popularity of the tag plays a role here too.
Disclaimer, this is just my theory from wandering around this platform :D
Nice words, one thing that may scary me a little bit is that this kind of tips may help people to never implementing some kind of architecture or abstractions or things just because we need to "move faster", like the other side of the coin, not having abstractions is also a problem, WDYT?
Hi Daniel, my intention was not to say that you should avoid abstraction. It is that you should be aware of its cost and to know where, when and how much to apply it. Often times articles touch only on the positive side of things, which can trick entry level engineers into thinking that a particular pattern, technology or architecture is without cost and should be applied everywhere and always.
One example would be the JWT token, which could often times be replaced with a basic bearer token, depending on your use case.
Giovanni gave a good heuristic, go with the Pareto's principle, and never forget that your job as an engineer is to provide value to the business. To do so, it helps to reduce cost of development to a reasonable minimum, but of course no lower than that.