Reading C̶l̶e̶a̶n̶ C̶o̶d̶e̶ Refactoring Week 4

Jacob on Software
Level Up Coding
Published in
7 min readJul 13, 2021

--

I’ve been loving reading through Clean Code, but am taking a bit of a break this week to discuss the first chapter of Martin Fowler’s Refactoring. Like Clean Code, Refactoring is fairly famous amongst professional programmers for its clear and concise advice on how to write clean, readable, and highly effective code. Now in its second edition and containing incredible insights from Fowler, Refactoring is frequently included in lists of the best programming books available (Seriously, I just googled “Best Programming Books” and it is listed in each of the top four results). With that, let’s dive straight into some of the lessons Fowler presents in chapter one.

One of the first lines in Refactoring emphasizes that learning about code requires examples, lest you nod off trying to understand an abstract computer science subject. In that same vein, I’m going to use Refactoring to edit my previous code for Putrid Potatoes, a social media application that allows you to review the movies you watch and interact with other users on the site. While I always aim to write clear, professional code, in making this capstone project for the Flatiron School I’ll admit some of the code that I wrote could be improved.

Putrid Potatoes homepage

More specifically, I’ll be refactoring a single React component from this application, the UserProfile component. This component is fairly straightforward, serving as a user’s personal profile page, containing a list of their followers as well as their personal movie reviews. The code for this component can be found here, and here’s an example of what it looks like in the browser:

Profile page for Putrid Potatoes

While the code for this component works perfectly well, it isn’t the most readable to other developers. As I’ve mentioned in previous blog posts, your compiler doesn’t really care if your code is readable to other people; if you really wanted to write your programs in as few lines as possible your IDE would probably accommodate you. But code readability is incredibly important to the other developers on your team. For Fowler, readability first becomes crucial in thinking about structure. Or, as Fowler says much more eloquently:

“When you have to add a feature to a program but the code is not structure in a convenient way, first refactor the program to make it easy to add the feature, then add the feature.”

Although it might seem obvious, I think what Fowler is saying here is a version of the “measure twice, cut one” philosophy that is more or less a staple of good engineering practice. Rather than hacking away at a program building out new and exciting features, experienced software engineers succeed when they lay a good foundation for their program, one that will be able to support features built today as well as in six months or a year. If you want to build applications all by your lonesome you should be fine maintaining any structure you want for your programs. However, as soon as you build things with even one other person, you’ll need to write readable code. To offer a simple example, let’s look at just some of the code forthe UserProfile component:

Again, this code works perfectly fine, but there are some pretty glaring problems with regard to its formatting. For one, these state management functions are awkwardly spaced out, and I can see there’s an unused variable of setReviews in my list of props for UserProfile.Worst of all, the props in allUserFriends is running off the page of my text editor! Thankfully, tools like Prettier make it incredibly easy to refactor:

I think you’ll agree that this code is much easier to understand than the previous example (or is at the very least more pleasant to look at), and while it’s only a small code snippet in a relatively small portion of the entire application, giving your programs structure is the first thing Fowler does when looking to refactor previously written code. Even though this edited code takes up more lines than the previous snippet, it remains much easier to understand and build up over time.

Next we’ll look at the handleUpdateReview()function, which (maybe obviously) allows a user to update a previously submitted review for either its content or star rating. Here’s what that function looks like in my codebase:

Although this function is working well, the .then syntax for my Promise is a bit dated, and I’ve gotten feedback from my fellow software engineers that it would be better to use the more modern async-await syntax. Without getting into the specifics of that decision now, needing to make this change is a perfect example of why good refactoring is so important. As Fowler writes, “The true test of good code is how easy it is to change it.” The technologies we use will always need to be updated, and codebases will always require quality refactoring. Therefore, making our code modularized and flexible is the key to keeping our software efficient. After reformatting handleUpdateReview() with Prettier I have a pretty nice little piece of logic:

To be sure, this is a minor change to my program, encompassing only a couple of keystrokes. But though it seems like an insignificant change, it’s a good opportunity for me to save my program, test the altered feature to ensure it’s still working in the browser, and only then committing those changes with a version control system. This speaks to my favorite part of Refactoring’s first chapter.

Throughout the first chapter, Fowler reminds his reader that he is constantly, painstakingly checking his edits to ensure he has not broken his overall program. Indeed, Fowler’s phrase “compile-test-commit” appears on almost every page of the first chapter, serving as a coding mantra that he performs after every change to make sure he has not made a mistake. There are a few passages in the first chapter where Fowler even reminds the reader that even though he’s not explicitly writing “compile-test-commit” in the pages of Refactoring, it’s a regular part of his coding practice.

By running Putrid Potatoes locally I’m able to do something similar, testing changes in the browser before committing those changes and ultimately pushing them up to my hosting service at Netlify. Getting this kind of tight feedback loop will save you hours wasted if you were to just edit your programs blindly and save your changes to GitHub. To my mind, this practice gives a programmer a sense of the rhythm of refactoring, how editing your programs should always be accompanied with care and regular tests. It’s a reminder that after you’ve measured twice and cut once you should still double check that everything else still fits together. With modern tools like git, squashing your commits is easy to do, so making lots of commits in this broad refactoring phase won’t build up a lot of cruft when you do eventually push up your changes.

Martin Fowler lecturing

Before I started reading Refactoring and Clean Code, I had my reservations about reading these types of books. While it seemed like a good idea to learn more about the process of writing quality code, wouldn’t it be a better idea to actually be writing that code? To be honest, I still think interested readers need to strike a balance between learning coding best practices and writing that code. It’s important to note, though, that while you’re reading books like Refactoring, you’re likely to catch yourself thinking of its lessons when programming. In my experience, if you take the time to sit with these books and internalize their lessons, they’ll seep deeply into your developer brain, ensuring you write more readable and maintainable code. Next week I’ll return to Clean Code once again. I hope you’ll come back to read about my progress.

--

--