Refactoring: Refactorings/Extract Method
Jump to navigation
Jump to search
Turn a section of code inside a long method into its own method (shortens the long method). Resulting code looks more like easy-to-understand pseudocode.
Mechanics
- Create a new method, named after 'what it does (not how it does it)
- Note: If code in question is simple, only extract if new method better reveals intention. If you can't come up with a more meaningful name, don't extract the code.
- Copy extracted code from source method into new method
- Scan extracted code for references to local variables. Make these variables parameters
- Scan extracted code for temporary variables declared in source method. If so, declare them in target method instead.
- If any local variables inside source method are modified by extracted code, treat extracted code as a query and assign result to said variable
- {{note|If more than 1 modified variable, Split Temporary Variable or Replace Temp with Query
- Create function call to target method above extracted code; don't forget necessary local-scope variables for parameters
- Delete extracted code in source method, replacing it with function call from previous step.
- Check for unused temporary variables that have been declared inside the newly extracted method and remove them.
- Test
Example
Before
def print_owing(previous_amount)
outstanding = previous_amount * 1.2
# print banner
puts "*************************"
puts "***** Customer Owes *****"
puts "*************************"
# calculate outstanding
@orders.each do |order|
outstanding += order.amount
end
# print details
puts "name: #{@name}"
puts "amount: #{outstanding}"
end
After
def print_owing(previous_amount)
print_banner
outstanding = calculate_outstanding(previous_amount * 1.2)
print_details outstanding
end
def print_banner
puts "*************************"
puts "***** Customer Owes *****"
puts "*************************"
end
def calculate_outstanding(initial_value)
@orders.inject(initial_value) { |result, order| result + order.amount }
end
def print_details(outstanding)
puts "name: #{@name}"
puts "amount: #{outstanding}"
end