Extract Method
Before you begin: Functions, parameters, return values, and loops.
Extract Method moves a piece of code into a named method and replaces the original statements with a call to that method. Outside a class, the same move is usually called Extract Function. The goal is to explain a step or make it reusable without changing its behavior. 1
Original version: calculation inside a label
A game totals coins from several rewards and produces a label. Assume ordinary integer amounts whose sum fits in a C# integer.
public static class Rewards
{
public static string Label(int[] amounts)
{
int total = 0;
foreach (int amount in amounts)
{
total += amount;
}
return "Coins: " + total;
}
}Label contains both the loop and the text formatting. The loop is one coherent calculation we can name.
def label(amounts):
total = 0
for amount in amounts:
total += amount
return "Coins: " + str(total)label contains both the loop and the text formatting. The loop is one coherent calculation we can name.
Refactored version: give the calculation a name
public static class Rewards
{
private static int TotalCoins(int[] amounts)
{
int total = 0;
foreach (int amount in amounts)
{
total += amount;
}
return total;
}
public static string Label(int[] amounts)
{
return "Coins: " + TotalCoins(amounts);
}
}TotalCoins receives the array the loop needs and returns the value formatting needs. Rewards.Label(new[] { 3, 7 }) still returns Coins: 10.
def total_coins(amounts):
total = 0
for amount in amounts:
total += amount
return total
def label(amounts):
return "Coins: " + str(total_coins(amounts))total_coins receives the values the loop needs and returns the value formatting needs. label([3, 7]) still returns Coins: 10.
Check the move, not just the final number
The iteration order, additions, and formatting are unchanged. The empty array or list still yields Coins: 0. Those comparisons are useful checks, though a few examples do not prove equivalence for every possible input.
Before extracting, identify values read from outside the selected statements and values used afterward. Pass required inputs and return required results. Be careful with mutations, early returns, exceptions, and evaluation order; a helper call must not quietly duplicate a side effect.
There is no rule that every three-line loop needs a method. Extract when the name saves the reader work, separates a meaningful calculation, or supports reuse. A helper named DoTheNextThreeLines has moved the code without explaining it.
Sources
- Martin Fowler — Extract Function, also known as Extract Method.