There must be a special place where all the abstractions that were never needed, but still built, go when a project is abandoned. Today I want to talk about optimising for frequency. What I mean by that is to make the things you do often during development of a thing really easy, while not getting too busy optimising for cases that rarely happen.
When you build a kitchen, you make it easy to cook food in it - and eventually you also want it to be cozy, or roomy, or practical, or whatever your preference is. But you optimise, very immediately, for the most common use cases. That's good.
Whenever I see an ORM, a piece of software that abstracts implementation details of a database technology away from the developer to make it possible to flexibly switch database systems, I'm chuckling a bit. There's plenty of really good use cases on why you want to use a generic ORM - it might really make your life easier, solve some common issues and so on - but how often do you really exchange your database? I've been in plenty of projects, and that was a very rare occurrence. Upgrading from one major version to a newer one, sure. But completely changing? Rather not.
Same reaction I get when I see folks abstracting away S3 into their generic file storage provider and - how likely are you to actually replace AWS as your primary cloud solution provider? And if so, is the dependency on S3 really going to be an issue?
And we're slowly moving to the point that I want to make: Don't spent time on optimising for things that will never happen. Some codebases feel like the software engineering version of a prepper tried to prepare the system for all possible outcomes, conveniently dropping readability and accessibility on the way. Do not be that person.
Here's what you want to optimise for. Statistically, your code will be read by humans - often. So the first thing you want to do is not optimise for readability, but optimise for clarity. A very obfuscated code base is hard to work in, hard to spot problems in and hard to change. Clean code, easy code and understandable code are rocket fuel for productivity.
Secondly, your code will be built and run very often. Optimise for fast builds and a convenient and easy way to debug both locally and get actionable insights from your production environment - some APM should do the trick.
Thirdly, your code will get changed a lot. So optimise for change. Make it easy to change things without breaking the whole thing, have a QA strategy that supports your team in getting changes out in a safe and reliable way.
And once you're good at having readable code that's fast to run and safe to change, you can maybe think about building some useless abstractions that don't solve a single problem you actually have.
But you can of course also just not do that.