In “Refactoring, Improving the Design of Existing Code” by Martin Fowler, he presents the Extract Method refactoring. It is one of the best refactorings out there. It’s one of the most common ones that I use.
Here’s a video walkthrough of the Extract Method refactoring and its benefits:
Video Transcription
Hey, what’s up everybody, it’s Andy from cleanswifter.com, and I’m back this week to actually continue our series on reading “Refactoring, Improving the Design of Existing Code” by Martin Fowler. This week for the first time, we’re going to look at an actual refactoring in code. The refactoring we’re going to look at is called “Extract Method.” Extract Method is actually a really easy refactoring, it’s often supported by IDEs and the benefit of it is that it increases the opportunity for code reuse, you’ll have less duplication of your code, it enables smaller units of code, so it helps you get rid of those really long methods. And it also reduces the semantic distance between the method name and method purpose. I really like that wording that Fowler actually used in the book. That means your method names will be very clear and close to what the method actually does. As a result, for that to happen, your method needs to be succinct and cohesive. Extract method refactoring enables this. Let’s take a look at it.
Here’s a class, AccountViewController
that subclasses UIViewController.
Right here in viewDidLoad()
is some simple code that creates two UILabels
. Three properties are set on each label: the text color, the text alignment, and the number of lines. There are actually two different labels on which these properties are being set. But what’s in common between these two pieces of code, is that, the three properties are being set on the label are exactly the same. This is a prime opportunity to leverage the Extract Method refactoring. For Extract Method, all we’re going to do is create a new method called setUpLabel
. In there, I’ll add a parameter that is the label to be set, and on that label, I’ll take this code, remove it from viewDidLoad()
and add it to this new method that we’re extracting, and then down in viewDidLoad()
, call the new method by providing the label. Down where the second label is setup, I can also then delete this code and call that same method with the addressLabel
. Now you can see we’ve removed the redundant code that is setting up the label, and now we have a dedicated method that is named very clearly for what it does: sets up a label. The redundant code for addressLabel
has also been consolidated.
Let’s make the example a little more complicated. In this example we see the similar three lines of code setting up the label that configure the text color, the text alignment, and the number of lines. To make it a little more complicated, we’re actually going to set the text on the two labels as well. nameLabel
will be set to “Andy” and addressLabel
will be set to “Philadelphia.” Now we want to perform a refactoring that removes redundancy while also preserving the ability to set the test on the labels. We’ll start off in the same way as before, creating the new method setUpLabel
. Move forward with the refactoring to get to the same point we were at in the last example. Now that a baseline for setUpLabel
is extracted, we need to update it to be able to accept a String
such that the text on the label may be set, and the redundant use of temporary variables in viewDidLoad()
can be removed. Add a parameter to setUpLabel
of type String
called text
. Set the text on the UILabel
‘s text
. Update the method call to setUpLabel
in viewDidLoad
to actually pass in the text to be set. Do the same thing for addressLabel
. At this point, we’ve removed redundancy and consolidated the code which includes setting the label’s text based on a provided parameter. There’s one more level of complication that we can add while leveraging the Extract Method refactoring.
Increasing the complexity of the example towards something even more real-life is to add properties on the view controller for each label so the values that are created are stored. After setUpLabel
is called, we’re now storing the label in the property on the class. To further reduce the redundant code, I’m going to extract the label creation into setUpLabel
. That will cause me to return the created label so that it can be set on the property. The goal of what I want to do here, is delete the creation of the UILabel
in viewDidLoad()
and move it to setUpLabel()
. I will no longer need to pass the created label in to setUpLabel()
. Instead, I will create a new UILabel
each time setUpLabel
is called. Then using that new label, set it’s properties, and return it. Now you can see the final result of the refactoring where all the redundant code has been consolidated into one place, a method dedicated to setting up labels. viewDidLoad()
now reads very clearly.
You just saw an example of the Extract Method refactoring. Just to recap it’s benefits: it increases the opportunity for code reuse by reducing duplication, it enables smaller pieces of code (as you saw viewDidLoad
and setUpLabel
become small). And finally, decreases the semantic distance between the method name and method purpose – which means you can create a nice small method with a nice clear name that reflects what the method does.
I hope you liked this screencast on the Extract Method refactoring from “Refactoring, Improving the Design of Existing Code” by Martin Fowler.
2 thoughts on “VIDEO: Extract Method Refactoring”