Last time, we looked at possibly one of the smallest refactorings you can do, Extract Variable. Let's take another tiny step and look at the Extract Method pattern.
Extract Method can be used when you have several expressions, a code fragment, that can be grouped together. Even if there is one expression that could be better explained with a well thought out method name, it’s still a good move.
Let’s use Extract method on the Invoice#print
method:
Before:
class Invoice
...
def print
print_branding
# print line items
line_items.each do |line_item|
puts "#{line_item.name}: #{line_item.price}"
end
# print subtotal
puts "Subtotal: #{line_items.sum(&:price)}"
end
end
After:
class Invoice
...
def print
print_branding
print_line_items
print_subtotal
end
private
def print_line_items
line_items.each do |line_item|
puts "#{line_item.name}: #{line_item.price}"
end
end
def print_subtotal
puts "Subtotal: #{line_items.sum(&:price)}"
end
end
The method before refactoring looks like:
def print
print_branding
# print line items
line_items.each do |line_item|
puts "#{line_item.name}: #{line_item.price}"
end
# print subtotal
puts "Subtotal: #{line_items.sum(&:price)}"
end
Often times, if you see comments explaining what a code fragment does, it’s a smell indicating there is a method to be extracted.
The method after refactoring looks like:
def print
print_branding
print_line_items
print_subtotal
end
Let’s walk through the steps used when applying Extract Method:
- Identify candidate fragments by looking for some common smells like, expressions that cluster together, comments explaining the intent, or if a good method name could add clarity.
- Turn those fragments into a method whose name explains the purpose of the method.
Reach for this when a method contains groups of seemingly un-related code fragments, or when better naming will make it easier for you or your coworkers to understand the intent of code.
Top comments (0)