John K. Ferguson

Refactoring with Love

June 26, 2026

I started working as a software engineer back in 2013.

Before that, I didn’t know much about how to code, but I knew that I wanted to learn and I wanted to build.

I joined the Flatiron School, one of the first programming bootcamps at the time. We learned Ruby and Rails. It was the proverbial drinking from the firehose type of experience, and I loved it. Shortly after graduation, I got my first job as a software engineer.

I started at a small place called NYC Dev Shop, a team of nine people with four engineers. We took on greenfield Ruby on Rails projects from other businesses, which was a good level of complexity for me at the time. I was able to keep learning and building.

Some time after that, I got a new job. This time at a company called AlphaSights. They were a much bigger company of about 150 people and ~15 engineers and had offices in London, New York, and Hong Kong.

Unlike NYC Dev Shop, the codebases I now worked on were not greenfield, and some had many years of commits behind them. This was quite a change. I now often had to do detective work to understand the codebase before starting a feature.

In the beginning, I mostly worked on some of the smaller apps we had. This suited me well and I was able to continuously improve my skills and my confidence.

Over time I got assigned larger and more complex features. And I had to delve into areas of the codebase that were more complicated and less familiar to me.

Understanding & Writing Code

When I would tackle a piece of unfamiliar code that I needed to understand, I’d follow a simple internal algorithm: trace the logic, consider what it was doing, what it was supposed to be doing, and build up an internal map in my mind.

As I went through this process of understanding the code, sometimes I’d notice unnecessary hoops I’d have to go through to understand what the code was actual doing. There might be a variable or method name that was misleading or vague. Perhaps a public method had many lines of internal code whose purpose or reasoning was opaque. Or there could be some bit of logic that didn’t have the appropriate test coverage.

When my internal mental map was complete, I’d compare it to what the actual code expressed. When there was a big gap between the two, I’d refactor to clarity.

To do that, I might rename a variable or method name, or extract some internal code to a private method and give it a more expressive name or add some missing test(s), etc. I’d pass on making changes that were mere preferences of mine and focused more on things that made the code clearer.

When I was finished, I’d look over the code. Its logic and intent would now be more transparent.

I’d feel good about that.

But more than just feeling good, I’d often feel love.

The image or idea would show up in my mind of someone coming across the code at some point in the future and that person having a bit easier time understanding it than I did it. And I’d feel a sense of love and well-wishing for this unknown potential person. Just a loving wish that the work I had done would make things a bit easier for them. Then I’d make my commit and go on to working on the actual feature.

I’d eventually get to a point where I was wrapping up the feature and perhaps there was some needed refactoring too in the code I had just wrote. I’d run the mental map algorithm and if changes were needed, I’d make them. Sometimes that well-wishing loving feeling would come up again and I’d feel it spreading out towards some possible person(s) in some possible future(s).

As I worked more and more in the codebase, I might come across code I had written previously. I’d recall the care and attention I’d put in it and it’d make me smile.

Facing Technical Debt

When facing technical debt, there is an opportunity to express love.

The code can be written, the changes made, and the opportunity may be accepted or declined.

Not just in programming, but in anything.

To take something, make it a little better, and then give it away to some unknown potential future with love.

Debt can come in many forms, not just as technical debt.

Things can be broken, inefficient, out of sorts or messy.

To be grateful for that mess is to see its opportunity: as the playground for love to express itself.

Catching up with a Friend

I worked at AlphaSights for a few years.

During my stay there, I worked on some fun and interesting projects. My favorite was working on Speak, an automated interactive call system for connecting our clients with experts. For a brief time, I was sole engineer put in charge of taking that existing codebase and turning it into a more refined version 2.0. Working with call systems was quite different than the work I had done previously and I found it quite interesting. By the end of the project, I had put quite a bit of my signature on that codebase.

About eight years after leaving, I was catching up with Ed, a friend and fellow AlphaSights engineer who was there during my time and had stayed on for many years after. We talked aobut some of the work he had been doing, and he told me that he had recently worked on the same project I had, Speak. It had been running for years, mostly as I left it, and they had Ed take it to a more feature rich version 3.0. We talked about the codebase, what it was like working on it, live testing calls, all the good stuff. I enjoyed hearing about that code and in my mind, I got flashes of parts of the codebase I had written.

I mentioned that it had been the favorite project I had worked on at AlphaSights. He agreed. It was one of his favorites, and he really enjoyed working on it too.

That made me smile.