Refactoring: Refactorings/Replace Method with Method Object
Jump to navigation
Jump to search
Turns a method into its own object so local variables become instance variables on that object. Code then becomes much easier to refactor in other ways.
Useful in a long method that uses local variables so you can't use Extract Method.
Mechanics
- Create a new class. Name it after the method
- Give the new class an attribute for the object that once hosted the original method (source object), and an attribute for temporary variables and parameters in the method
- Give the new class a constructor that takes the source object and each parameter
- Give the new class a method named "compute"
- Copy the body of the original method into compute, using the source object instance variable for any reference to methods on the source object
- Test
- Replace old method with one that creates new object and calls compute.
Example
Before
class Account
def gamma(input_val, quantity, year_to_date)
important_value1 = (input_val * quantity) + delta
important_value2 = (input_val * year_to_date) + 100
if (year_to_date - important_value1) > 100
important_value2 -= 20
end
important_value3 = important_value2 * 7
# ...
important_value3 - 2 * important_value1
end
end
After
class Gamma
attr_reader :account, :input_val, :quantity, :year_to_date, :important_value1, :important_value2, :important_value3
def initialize(account, input_val_arg, quantity_arg, year_to_date_arg)
@account = account
@input_val = input_val_arg
@quantity = quantity_arg
@year_to_date = year_to_date_arg
end
def compute
@important_value1 = (input_val * quantity) + @account.delta
@important_value2 = (input_val * year_to_date) + 100
if (year_to_date - important_value1) > 100 # now we could easily Extract Method on this
@important_value2 -= 20
end
@important_value3 = important_value2 * 7
# ...
@important_value3 - 2 * important_value1
end
end
class Account
def gamma(input_val, quantity, year_to_date)
Gamma.new(self, input_val, quantity, year_to_date).compute
end
end