Refactoring: Refactorings/Move Method
Jump to navigation
Jump to search
If a method is using (or will be used) by more features of another class than the one on which it is defined, then it should be moved into that class.
Mechanics
- Examine all features used by the source method that are defined on the source class. Consider whether they should be moved
- Note: If a feature is used only by the method you are about to move, you might as well move it too. If the feature is used by other methods, consider moving them as well. Sometimes it's easier to move a clutch of methods than to move them one at a time.
- Check the sub- and superclasses of the source class for overriding definitions of the method. (If there are other definitions, you may not be able to move unless polymorphism can also be expressed on the target.)
- Define the method in the target class. (Choose a more descriptive name if necessary)
- Copy the code from the source method to the target. Adjust the method to make it work in its new home.
- Note: If the method uses its source, try passing in the source object reference as a parameter
- Determine how to reference the correct target object from the source
- Turn the source method into a delegating method
- Test
- Decide whether to remove the source method or retain it as a delegating method. (leave as a delegating method if it has many references)
- If source method is removed, replace all of its references with references to the new target method
- Test
Example
Suppose there will be multiple types of accounts, each of which will have its own method of calculating overdraft charges. overdraft_charge should really be on the AccountType superclass.
Before
class Account
def overdraft_charge
if @account_type.premium?
result = 10
result += (@days_overdrawn - 7) * 0.85 if @days_overdrawn > 7
result
else
@days_overdrawn * 1.75
end
end
def bank_charge
result = 4.5
result += overdraft_charge if @days_overdrawn > 0
result
end
end
After
class AccountType
def overdraft_charge(account)
if premium?
result = 10
if account.days_overdrawn > 7
result += (account.days_overdrawn - 7) * 0.85
end
result
else
account.days_overdrawn * 1.75
end
end
end
class Account
def bank_charge
result = 4.5
if @days_overdrawn > 0
result += @account_type.overdraft_charge(self)
end
result
end
end