October 8, 2017

...Learn TDD with Codemanship

Manual Refactoring : Extract Method

Another commonly used refactoring is Extract Method. We may wish to extract a block of code or an expression that's repeated multiple times into a shared method, for example. Or break down a long method into a composed method, or document code by using a method name to explain what it does.

In this example, I have some test set-up code that's repeated three times. I'd like to extract this into a shared method which I can parameterise to make it reusable in all three instances.

This example is fairly straightforward. I just need to cut the repeated code from the first test and replace it with a call to a new method that I've yet to declare.

Then I declare the method create_quote(), and paste in the code I cut from the test. Because the object carpet_quote is referenced further down (in the test assertion), it needs to be a return value of this new method.


Now I'm free to introduce parameters for price per square metre and room width and length to make it reusable in the other tests.

In a slightly more nuanced example, the code we want to extract into a method references variables that are declared outside of that code.

Here, we'll need to introduce these parameters from the start. Again, cut the code we want to extract and replace it with a method call, this time passing in those variables.

Now declare the new method - with parameters - and paste in the extracted code.


So, the process is quite straightforward.

1. First, cut the code you want to extract into a new method. Note that this code must executable in its own right - a statement, a block of code or an expression.

2. Identify any inputs - that is, references to variables declared before the extracted code.

3. Replace with a call to the new method, complete with any required input parameters.

4. Declare the new method and paste in the extracted code. If a variable is referenced after the extracted code, it will need to be made a return value.

5. Run your tests!

You've probably figured out that this won't work if there's more than one return value, so that would be a pre-condition to the Extract Method refactoring. In those cases, we can find other ways to act on a variable without passing it back (e.g., make it a field, or pass it by reference if the language allows that).

Posted 3 years, 2 months ago on October 8, 2017