Refactoring to Understand

I’ve been working on a large front-end application for the past several months. The code base is mature and has its own unique style. I started out on the project adding new features, following the patterns already established. I didn’t consider the architecture much — partly because I didn’t need to, and partly because it was overwhelming. After I became familiar with it I began to understand some of the patterns, but still could not grasp the entirety of it.

It wasn’t until I had the chance to refactor some pieces that it finally clicked. Looking at the code with the ‘refactoring’ mindset opened up my view. When writing a new feature, writing new code, it’s easy to get tunnel vision — follow existing patterns because they’re understood. The release deadline is close, this piece is blocking the next task, whatever — they’re all reasons to focus small. Refactoring made me think about abstractions over specifics, which forced me to reason about the system.

A refactoring mindset pushed me focus on why a function or module was written as it was. The reasons for focusing small don’t exist. Were there assumptions that proved to be false? Does this function serve its original intent? Same question, but for the entire module? Does following existing patterns negatively affect how this function was written? It also exposes bad testing — if I refactor the implementation of a function and tests fail, were those tests just noise? Again, it pushes focus to the why, rather than tunnel vision on how.

I haven’t spent much time thinking about it besides this — I had a spark of insight and decided to write it down. I could see the argument that code reviews should catch those why questions, or that architectural concerns should always be in mind when writing new code. They aren’t always though, and looking at code with refactoring in mind helps me read it differently — and better.