Always Be Refactoring
Great engineers refactor constantly, even if they have to slip it into their normal workflow. “Always be closing.” The hard-nosed sales mantra from Glengarry Glen Ross became shorthand for relentless improvement. In the same spirit (but with much less swearing), a good engineer should always be refactoring. Here’s why. To Clean or Not to Clean It’s generally agreed that clean code is easier to understand, cheaper to maintain, and much more extensible. At its core, refactoring is cleaning up existing code without altering its perceived functionality. A common objection to refactoring is that there isn’t time to actually do it. Teams see it as a luxury. The relentless drive for new features simply doesn’t allow for refactoring, especially because refactoring changes nothing from an external point of view. That can be a hard sell to your product owner. But clean code makes your life easier. Clean code pays for itself and slows the accumulation of technical debt. So sneak it in. That’s right. I’m suggesting a slight bit of subterfuge. A little misdirection even. Why not clean up a few things in every pull request? Be Vigilant A good engineer has a vision of where the codebase should be heading. It might take a while to get there, but you know the messy parts, the backlog, the roadmap, the technical debt, the security holes, and the documentation gaps. As you go about your regular feature development, be on the lookout for refactorings that can advance your larger agenda. Like one of those hyper-observant TV show detectives surveying a crime scene, pay close attention to all the code you stumble across. When you notice a code smell or something slightly off near your current focus, alarm bells should go off: “Don’t let this opportunity pass!” Take a few minutes and fix it now, before inspiration fades. Don’t say it’s not your problem. Don’t pretend you can unsee it. Just roll up your sleeves and get it done. A Simple Example Refactoring doesn’t necessarily mean changing thousands of lines of code. It can be just a small chunk of code here and there. These little micro-refactorings add up over time. In fact, the more you get into the habit of constant cleanup, the less you will need to do major refactorings in the future. To illustrate micro-refactoring, let’s look at an “extract method” Golang example. Let’s say you are tackling a feature that requires knowing how many days it has been since a user last logged in. You notice an existing method that determines if a user is dormant by using that same information: func IsDormant(user User, asOf time.Time) bool { days := int(asOf.Sub(user.LastLogin).Hours() / 24) return days >= 8 } You want to re-use the last login calculation instead of copying and pasting it, so you take the internal variable, days, and extracting it into a separate method, DaysSinceLastLogin: func IsDormant(user User, asOf time.Time) bool { return DaysSinceLastLogin(user, asOf) >= 8 } func DaysSinceLastLogin(user User, asOf time.Time) int { return int(asOf.Sub(user.LastLogin).Hours() / 24) } This allows the last login logic to be tested and reused. If you write a unit test, you’ll spot an edge case that should be handled (a potential panic if a user has never logged in). It also makes future enhancements easier. For example, it might make sense to make IsDormant and DaysSinceLastLogin methods on the User struct instead of being standalone. Likewise, consider replacing the hard-coded value 8 with something more descriptive like DormantDaysThreshold. This is a simple example, just a few lines of code. But that’s the beauty. It shows a small refactoring can add value by revealing a potential bug and pointing towards future improvements. To learn more about the craft of refactoring and see all the small ways to improve your code, check out online resources such as the refactoring catalog from Martin Fowler’s book or the Refactoring Guru. A Refactoring Mindset Having a vision for your codebase is easy. Knowing how to get it there is harder. Spotting refactoring opportunities takes practice. One way to get started is to consider which categories of refactoring are necessary to transform your code. Here are some common refactoring themes to think about:

Great engineers refactor constantly, even if they have to slip it into their normal workflow.
“Always be closing.”
The hard-nosed sales mantra from Glengarry Glen Ross became shorthand for relentless improvement. In the same spirit (but with much less swearing), a good engineer should always be refactoring. Here’s why.
To Clean or Not to Clean
It’s generally agreed that clean code is easier to understand, cheaper to maintain, and much more extensible. At its core, refactoring is cleaning up existing code without altering its perceived functionality.
A common objection to refactoring is that there isn’t time to actually do it. Teams see it as a luxury. The relentless drive for new features simply doesn’t allow for refactoring, especially because refactoring changes nothing from an external point of view. That can be a hard sell to your product owner.
But clean code makes your life easier. Clean code pays for itself and slows the accumulation of technical debt.
So sneak it in.
That’s right. I’m suggesting a slight bit of subterfuge. A little misdirection even. Why not clean up a few things in every pull request?
Be Vigilant
A good engineer has a vision of where the codebase should be heading. It might take a while to get there, but you know the messy parts, the backlog, the roadmap, the technical debt, the security holes, and the documentation gaps.
As you go about your regular feature development, be on the lookout for refactorings that can advance your larger agenda. Like one of those hyper-observant TV show detectives surveying a crime scene, pay close attention to all the code you stumble across.
When you notice a code smell or something slightly off near your current focus, alarm bells should go off: “Don’t let this opportunity pass!” Take a few minutes and fix it now, before inspiration fades.
Don’t say it’s not your problem. Don’t pretend you can unsee it. Just roll up your sleeves and get it done.
A Simple Example
Refactoring doesn’t necessarily mean changing thousands of lines of code. It can be just a small chunk of code here and there. These little micro-refactorings add up over time. In fact, the more you get into the habit of constant cleanup, the less you will need to do major refactorings in the future.
To illustrate micro-refactoring, let’s look at an “extract method” Golang example.
Let’s say you are tackling a feature that requires knowing how many days it has been since a user last logged in. You notice an existing method that determines if a user is dormant by using that same information:
func IsDormant(user User, asOf time.Time) bool {
days := int(asOf.Sub(user.LastLogin).Hours() / 24)
return days >= 8
}
You want to re-use the last login calculation instead of copying and pasting it, so you take the internal variable, days
, and extracting it into a separate method, DaysSinceLastLogin
:
func IsDormant(user User, asOf time.Time) bool {
return DaysSinceLastLogin(user, asOf) >= 8
}
func DaysSinceLastLogin(user User, asOf time.Time) int {
return int(asOf.Sub(user.LastLogin).Hours() / 24)
}
This allows the last login logic to be tested and reused. If you write a unit test, you’ll spot an edge case that should be handled (a potential panic if a user has never logged in).
It also makes future enhancements easier. For example, it might make sense to make IsDormant
and DaysSinceLastLogin
methods on the User struct instead of being standalone. Likewise, consider replacing the hard-coded value 8
with something more descriptive like DormantDaysThreshold
.
This is a simple example, just a few lines of code. But that’s the beauty. It shows a small refactoring can add value by revealing a potential bug and pointing towards future improvements.
To learn more about the craft of refactoring and see all the small ways to improve your code, check out online resources such as the refactoring catalog from Martin Fowler’s book or the Refactoring Guru.
A Refactoring Mindset
Having a vision for your codebase is easy. Knowing how to get it there is harder. Spotting refactoring opportunities takes practice. One way to get started is to consider which categories of refactoring are necessary to transform your code.
Here are some common refactoring themes to think about: