The feature of moving objects between reconstruction methods [1 ].
Total returned directory
Directory of this section
1. Move Method (migration function) Overview
In your program, there is a function that communicates with another class other than the class in which it is located: the latter is called, or is called or called.
Create a new function with similar behavior in the class most often referenced by this function. Convert the old function into a pure delegate function, or remove the old function completely.
Motivation
If a class has too many behaviors, or if a class is highly coupled with another class, or the number of times another object is used is more than the number of times the object is resident. Then we need to move the function.
When moving a function, you need to determine the moving path based on "The function communicates more with which object.
Example
This reconstruction is illustrated using an Account class that represents an "Account:
Class Account {private AccountType _ accountType; private int _ daysOverdrawn; /// <summary> /// overdraft billing rule /// </summary> /// <returns> </returns> double OverdraftCharge () {if (_ accountType. isPremium () {double result = 10; if (_ daysOverdrawn> 7) {result + = (_ daysOverdrawn-7) * 0.85;} return result ;} return _ daysOverdrawn * 1.75;} double BankCharge () {double result = 4.5; if (_ daysOverdrawn> 0) {result + = OverdraftCharge ();} return result ;}}
The AccountType class is as follows:
class AccountType{ public bool IsPremium() { return true; } }
Suppose there are several new accounts, each of which has its own "overdraft Payment Rules ". All OverdraftCharge () is moved to the AccountType class.
First, observe every feature used by OverdraftCharge () and consider whether it is worth moving them with OverdraftCharge. In this example, we need to leave the _ daysOverdrawn field in the Account class, because this value will not change with different types of accounts. Then, copy the code of the OverdraftCharge () function to AccountType and adjust it accordingly.
class AccountType{ public double OverdraftCharge(int daysOverdrawn) { if (IsPremium()) { double result = 10; if (daysOverdrawn > 7) { result += (daysOverdrawn - 7) * 0.85; } return result; } return daysOverdrawn * 1.75; } public bool IsPremium() { return true; }}
Then, replace the function ontology of the source function with a simple delegate action.
Class Account {// <summary> /// overdraft billing rules /// </summary> /// <returns> </returns> double OverdraftCharge () {return _ accountType. overdraftCharge (_ daysOverdrawn );}}
The reconstruction can end here. Of course, we can also delete the source function in the Account. Find all callers of the source function and redirect these calls to the BankCharge () of the Account ().
class Account{ private AccountType _accountType; private int _daysOverdrawn; double BankCharge() { double result = 4.5; if (_daysOverdrawn > 0) { result += _accountType.OverdraftCharge(_daysOverdrawn); } return result; }}
In this example, the removed function only references one field, so you only need to pass this field as a parameter to the target function. If the removed function calls another function in the Account, you can pass the source object to the target function.
class AccountType{ public double OverdraftCharge(Account account) { if (IsPremium()) { double result = 10; if (daysOverdrawn > 7) { result += (account.GetDaysOverdrawn() - 7) * 0.85; } return result; } return account.GetDaysOverdrawn()* 1.75; } public bool IsPremium() { return true; }}Summary
When moving a function, check all the features used by the source function in the source class and check whether they should also be moved. If a feature is used only by the function you intend to move, you should move it together. If other functions use this feature, you can consider moving all the functions that use this feature.
2. Move Field Overview
In your program, a field is used more by another class other than its resident class.
Create a field in the target class, modify all users of the Source Field, and change them to a new field.
Motivation
Moving status and behavior between classes is an essential measure in refactoring. With the development of the system, we will find that we need a new class and need to drag the existing work responsibilities to the new class.
If more functions are used for a field in another class other than its resident class, you must consider moving this field.
Example
Take the Account class as an example.
class Account{ private AccountType _accountType; private double _interestRate; double GetInterestForAmountByDays(double amount, int days) { return _interestRate * amount * days / 365; }}
We want to move _ interestRate to the AccountType class. Currently, several functions have been referenced. GetInterestForAmountByDays () is one of them.
Create a _ interestRate field in AccountType and encapsulate it as an attribute.
class AccountType{ private double _interestRate; public double InterestRate { get => _interestRate; set => _interestRate = value; }}
Now, let the function of the _ interestRate field accessed in the Account class use the AccountType object instead and delete the _ interestRate field in the Account class.
class Account{ private AccountType _accountType; double GetInterestForAmountByDays(double amount, int days) { return _accountType.InterestRate * amount * days / 365; }}Summary
For C #, This refactoring method may be called "moving attributes. Because the fields are basically private, attributes are accessible to other functions. Moving attributes is the same as in the example.
To Be Continued ......