You know the feeling. A simple feature request lands on your desk, and suddenly, you’re lost in a maze of refactoring. What was supposed to be a quick task turns into an endless series of tweaks and improvements, each one leading to the next. The idea of ‘always make the code slightly better’ sounds good, but in reality, it’s a constant balancing act between perfection and practicality.
I wanted to share my experiences navigating this tricky terrain - the times when a simple feature request led me down a rabbit hole of refactoring that consumed days or weeks, and the lessons I've learned about balancing code quality with pragmatism.
Never underestimate the importance of refactors
Not every refactor ends in frustration. In fact, sometimes, taking the time to improve the code can lead to big rewards—sometimes, it’s exactly what the project needs.
Case Study: The One with the Shared Model Layer
Every new feature felt like reinventing the wheel. I’d copy-paste a similar method from another model, tweak it, and hope I didn’t miss anything. It was tedious, error-prone, and far from sustainable.
First, some context:
We have dozens of models (aka entities) in Torii. And like many other applications, we support CRUD (Create, Read, Update, Delete) operations on each one of these models. A couple examples are:
Our App model supports fetching apps by id and/or by name, and checking if there are apps that match a certain criteria; our User model supports fetching users by name and/or email, and whether a user with a given email exists; our Org model supports fetching organizations by domain and/or name; and so on.
Do you recognize the pattern?
For a long time, we had repetitive CRUD methods scattered across models. Not only was our code repetitive, writing raw SQL was often annoying and prone to errors.
Why not just use an ORM? Two reasons:
First, we still believe raw SQL queries have lots of advantages; Second, incorporating an ORM into our codebase at this point meant changes on a much larger scale, which would have taken us a lot more time and would have been very risky.
Back to my story, frustrated by the endless cycle of copy-pasting and tweaking methods, I decided enough was enough. It was time to break the pattern and build something sustainable: