You might’ve encountered this quote from Donald Knuth’s book “The Art of Computer Programming”:
“Premature optimization is the root of all evil.”
It’s pretty common for us software engineers to overengineer things. The opportunity is usually right there and it can be so easy to imagine a bit of extra abstraction that appears to fit just right. But quite often our guesses are wrong, because we can’t actually see the future. Tragic, I know.
Here’s a step-by-step guide for avoiding this pitfall:
Obviously, you have to solve the actual problem in front of you.
If you’re building an email notification system, build an email notification system. Build the services you need to generate email contents, interact with your email service provider, and whatever else you need for the thing to do what it’s actually supposed to do.
Less obviously, it’s probably OK to go a little beyond the scope of the current project if a bit of effort can go a long way toward making life easier down the line.
If you’re building an email notification system, maybe you can store notifications in the database with
type="email", anticipating other kinds of notifications. And maybe your services for dispatching requests to your email service provider can send any kind of email, and the caller supplies all the data.
That’s the sixty four thousand dollar question!
In my experience, most work done to futureproof something makes it more complicated to maintain before said future arrives. It then stands to reason that the decision about whether or not to do it is largely driven by how likely the target future use cases are, how well they’re presently known, and what the anticipated cost of refactoring is.
Don’t solve problems you think you might have some day. Don’t try and support every imaginable variation of every feature.
Don’t build push notifications just because you’re in there already. Don’t add enterprise features for a hobby-level project. Don’t optimize for seven hundred thousand concurrent users before you’ve even launched. Don’t abstract utilities to accommodate use cases not even on your road map. Don’t invent problems with a false sense of urgency.
Resist the temptation. You probably have something more important you could do instead. Go do that.