As many other engineers, i remember reading Clean Code by uncle bob, pragmatic developer etc and how much it changed my mindset, i became fanatical about thinks like DRY, SOLID etc
In this industry its very easy to get lost, and loose your mind to buzzwords, and "Best Practices" .. As i grow in my career, stacking more lines of code every day under my portfolio, i become more convinced more than ever that maybe i should think for myself, i should weigh and judge what exactly "best practises" are in the context of whatever i am working on.
Weeks ago, i and and my team lead were talking about refactoring some piece of code that was just becoming larger and larger, and surely enough, first though came to mind, Why dont we abstract things into a shared library and have those two pieces of code just reference it. And my team lead was like "how are we sure that shared implementation would cover the usecase for these two pieces of code we want to refactor into"
I paused for a minute and thought, and realised it actually made sense.. At that point in the solution we didnt know for sure the business rules that these two pieces of solutions might require, worst still what if along the line, business comes back to us and require a change in process for one of the solution alone.
Few weeks later, there was a slight change in the requirement, thankfully we didnt go the abstraction route, i was easily able to modify the behaviour based on the new requirement without having to think about how it affects the other solution.
I now thought about it later on, if i had gone the route of abstraction and we somehow threw in a bunch of If statements, or some complex design pattern, and more changes to requirements came in, and we had to keep changing that abstraction to support the two solutions, we would have very easily rebuilt the same original code we tried to refactor away from, essentially building this monster everybody who works on that code would be afraid of.
The truth is, in many of our codebases, this same problem keeps happening over and over again, mainly because of The "Best Practises" BS somebody sold to us, we over abstract things, layers and layers of abstraction, microservices, interfaces, abstract classes, factory pattern, DRY etc the list keeps going.
Many thanks to Dan Abrahmov In his article Goodbye, Clean Code and his talk The Wet Codebase, it allowed me to rethink solutions, maybe a simple code that is easy to read and modify is better than "Clean Code" where any change comes with a cost.
Nowadays, i have a checklist of items that guides me when it comes to abstractions, and DRY principle
Is the code core business logic ? - Business rules can always change, it is better to have code duplications that can permit this change.
Is the proposed abstraction doing only one thing (SRP) - One of the dangers of abstraction is when you have a particular abstraction doing more than one thing, for example say after a user registers on you platform and you want to send an email, do you have an Email service abstraction ? or have a Notification abstraction that encapsulates email processes under ?
In summary, i am a strong advocate for simplicity in code, i think for each design and implementation we push out everyday we should form our own "Best Practises", allow the business dictate what is best and not over think and over engineer solutions that might never be.