Is your code difficult to work with? Chances are, it’s time to get rid of code you don’t need. That can be a scary prospect, but the rewards can be well worth the effort.
Recently, I was inspired by KonMari, a technique for decluttering physical spaces, to help me visualize how to refactor codebases to make them easier to work with.
Last summer, as I bounced my three-month-old daughter on my knee while visiting my in-laws, a half-joke slipped through the clutch between my brain and my mouth.
“It would just be easier if we LIVED here.”
And to my surprise, my mother-in-law replied, “You know that’s an option, right? We would love that.”
Thus began the great merging. Scott and I were both starting our careers on the speaker circuit, and the increased travel required us to lean on his parents for child care more and more. Luckily, Ann and Steve, Scott’s parents, wanted to be a significant part of our children’s lives and, after careful consideration, we decided to take them up on the offer.
We discovered that merging two households together is significantly more effort than moving from a full house into an empty one. The biggest challenge is handling all the STUFF. We were trying to squeeze the belongings of a 1700 square-foot house into two bedrooms, one for us, and one for the kids.
Around the time of the move, I stumbled on a book by Marie Kondo, The Life Changing Magic of Tidying Up. The advice in this book, although brief, was profound. Kondo described her method, which she called KonMari, for helping clients eliminate clutter and create physical environments that are a joy to live in. Her advice is simple: “Effective tidying involves only two essential actions: discarding and deciding where to store things. Of the two, discarding must come first.”
As I went through the process of decluttering and organizing my house, I couldn’t help but see the process as a metaphor to working with codebases in the digital world. One of the biggest impediments to a productive development team is a cluttered codebase, just like how clutter inhibits joy in our living spaces.
To Kondo, the biggest hurdle her clients face is overcoming the psychological objections to discarding things. I find that to be true with code too. Often, I’ll find myself with a “maybe I’ll need this later” attitude when I’m working with a piece of code. There’s a battle going on in my brain. Should I delete something because it will make the codebase as a whole better? Or should I keep it because that’s easier in the moment?
I’ll also find that I go to refactor a piece of code and that ends up leading me down a long rabbit hole that I never intended to go down. The same thing happens with my physical space, especially now that I have constraints. I’ll decide that I want to organize a bin in my closet, but in order to do that properly, I have to remove the contents of pretty much the entire closet. Stuff gets strewn across the bed and in strange little piles on the floor while I’m trying to evaluate the system as a whole. What I anticipated was a ten-minute project ends up taking up an entire afternoon. This is fine when I plan for it, but when I get caught off guard by my own expectations, my initial feeling of empowerment quickly fades into feeling deflated.
The key to decluttering effectively lies in getting past the psychological hurdle of deleting. This is as true with physical objects as it is with digital ones. With KonMari, this takes place in two distinct phases: purging and maintaining. In the purging phase, you look at all of your objects in phases: clothing, books, papers, etc. Each item must pass a litmus test, not as to whether it should be deleted, but whether or not it should be kept. In Kondo’s words, “The best way to choose what to keep and what to throw away is to take each item in one’s hand and ask: ‘Does this spark joy?’ If it does, keep it. If not, dispose of it. This is not only the simplest but also the most accurate yardstick by which to judge.”
Looking at my living space systemically, while armed with a simple litmus test for each item I needed to evaluate, proved to be an incredibly powerful way to move through what I thought would be the intractable problem of merging two houses together. KonMari became a powerful metaphor for me as I approached my work at Corgibytes, too. Legacy code is often seen as difficult to work with because it’s unorganized and cluttered. I found myself searching for ways to apply the KonMari philosophy to my work with modernizing codebases, too.
I’ve found myself searching for a mantra to use as a litmus test for determining whether or not a piece of code should be kept. While I’ve tested out several in my mind, I have yet to find the right correlation to “does it spark joy?” I find myself thinking often of usefulness: Is this helpful? Does it contribute to code quality? Does it follow S.O.L.I.D principles? But I have yet to find a question that is as emotive and profound as sparking joy. I’d be very interested in hearing what other developers use throughout the course of their work.
As for systems, the most helpful one I’ve found is from Llewellyn Falco and Woody Zuill with their Practical Refactoring method. To me, it has the elegance and simplicity that I enjoyed so much about KonMari. Here’s a quick visualization:
Step 1: Remove Clutter
Organizing is so much easier when you have fewer things to manage. This is true in the physical world as well as the digital. Too often, we’re afraid to delete code, but it’s a necessary part of maintaining a healthy codebase, just like taking out the trash is a healthy part of maintaining a clean house. In my opinion, there are simply not enough code deletion tools out there. The world could really benefit from more minds thinking about how to safely remove dead code.
That being said, using one of the automated tools that do exist, such as Living Social’s CoverBand, to help identify and remove dead code is a good first step. Additionally, as a codebase continues to change, developers should not be afraid to delete dead code as it becomes obsolete. Utilizing test-driven development, peer code reviews, and other recommended development practices can help ensure that a codebase doesn’t become littered with new obsolete code.
Step 2: Split Long Methods
I’ve talked previously about how inception layers make it difficult to context switch. When refactoring code, I often find that I need to keep a mental model of long methods, or actions in the code, in my head to try to figure out what the heck a block of code is doing. By splitting up long methods, developers need to spend less mental energy trying to parse out the meaning of code. Refactoring long methods can be simplified using an IDE. JetBrains’ products have a particularly useful “extract method” feature that helps automate this task and ensure accuracy.
Step 3: Split Long Methods (again)
After taking a first pass at splitting up long methods, it makes sense to take a second pass over the newly-created methods. It’s likely that some of them are still a bit unwieldy. Plan extra time for these steps. Chances are you have a lot of room for improvement.
Step 4: Extract Classes
Now that we’ve reorganized and simplified our methods, or actions, we want to make sure that the classes, or categories, we’re using still make sense. If we’re using the analogy of organizing a closet, this step would be looking at all of the things we own and putting them in labeled bins of related items. The size and contents of each bin may be up for debate, but what is most important is that the bins are clearly and logically labeled. This helps us make sure that when we want to reference, or find, an object later, it will be easy.
Step 5: Create Abstraction
Next up, it’s time to look at the codebase as a whole and examine what elements can be lifted out of the details into a broader layer to make it even easier to reference. If I were organizing my closet, I might look at all of my bins and see that I could arrange things on shelves in broader categories like craft supplies, tools, files, seasonal decorations, etc. With my closet, this helps give me specific reference points for where I can find an object. We do the same thing in code with abstract classes.
Step 6: Add New Features
Yay! Our code is organized and easier to work with. This means that adding new features will be much easier. I think of this step as me actually using the contents of my closet to do a project, let’s say making a quilt for my kids. There are things I’ll need to pull out of the closet and things I’ll need to buy. I’ll use all of them together to create something useful and new. At this stage, it’s useful to remember that cleaning up after yourself is a critical part of good coding practices. It’s not just organizing something once and then going back to bad habits. Hopefully, every time you do a project, you’re finding small ways to keep your space tidy and a joy to work with.
It’s worth taking the time to review Llewellyn and Woody’s in-depth two-hour workshop where they dive into the details of this method. I love this because it maps brilliantly to the philosophy of KonMari. One of my favorite quotes is when Llewellyn says, “Code excellence is more about discipline than it is about brilliance.”
The key takeaway, for both physical and digital spaces is that we need to be disciplined and make deleting and organizing code a regular priority. Ignoring clutter only compounds it and makes a seemingly intractable problem even worse. Armed with a simple set of rules and making an effort is worth it. When you KonMari your code, you can transform frustration into joy.