Want to see the full-length video right now for free?

Sign In with GitHub for Free Access


Live Refactoring with Joe

In this episode, Chris is joined by thoughtbot CTO Joe Ferris.

With the magic of live-coding, Joe demonstrates how a simple Extract Class refactoring can lead to a host of code improvements.

You can see the full changes in this commit commit to the Namely Connect repo.

Extracting a class

Joe smells a code smell

Joe decides to extract a class when he notices that the Normalizer class refers to a payload object repeatedly (and passes it among nearly all its methods).

A common reaction to detecting this code smell is to extract a class to hold (and operate on) this data. This provides some noise reduction (since you no longer have to pass the data around) but also readability improvements and lower coupling.

Creating the Payload class

Joe begins by creating a private class inside the Normalizer class and moving appropriate methods inside it. This is a good first step that can later be promoted to a public class if desired.

The tests start failing

Joe gets bitten by a classic Ruby gotcha: referencing an instance variable that doesn't exist returns nil. You can hear Joe discuss why returning nil is developer-hostile in another Weekly Iteration episode, Nil is Unfriendly.

The tests go green

After a series of small changes and fixes, Joe's test are green again.

Take note of how Joe works in small steps and constantly re-runs his tests. A good TDD workflow allows you to run tests quickly from your editor. For more on that, see Speedy Tests.

The refactoring continues

So far, the improvement from the extracted class is minimal. However, the newly-extracted Payload class makes it easy to make a few additional improvements.

First, Joe moves the payload data into instance state. This allows Joe to remove the argument from many methods inside the new class, which provides the promised noise-reduction and lower coupling.

Remember: commits are cheap

While refactoring, it's a great idea to make small commits along the way. It's easy to do and can be extremely useful for restoring your code to a known-good state.

A moment of clarity

Payload's instance data allows Joe to delete a whole host of parameters.

However, when attempting to remove it from the custom_fields method, Joe discovers that the parameter is poorly-named. While called payload, it actually can be one of several objects. Rather than living with this duplicity, Joe renames the parameter on the spot. This is a nice example of constantly tidying a codebase.

More small cleanups

Joe continues to make small improvements in his new class: removing parameters, renaming methods, and a textbook Extract Temp to Query refactoring.

Closing thoughts

Before undertaking a refactoring, it can be hard to predict how much better the code will become. However, once the inital refactoring is complete the opportunity for additional cleanup often becomes apparent. Because of this phenomenon, it's a good idea to make any positive changes you can clearly see, since it may make several others obvious afterwards.