Motivation)
Extract Method is one of the most common refactoring methods. when we see a function that is too long or a piece of code that requires comments to make people understand the purpose, we will put this code into an independent function.
There are several reasons why we like short and well-named functions. first, if each function has a very small granularity (finely grained), there will be more opportunities for reuse between functions. Second, this will make the high-level Function Code read like a series of comments. Furthermore, if all functions are fine-grained, override is easier.
Indeed, if you are used to human functions, it may take some time to adapt to this new style. and only when you can give small functions a good name can they really play a role, so you need to work on the function name. people sometimes ask how long a function is suitable? In my opinion, the length is not a problem. The key lies in the scmantic distance between the function name and the function Ontology. If the extract action (extracting) can enhance the Definition of the code, so do it, even if the function name is longer than the extracted code.
Mechanism)
1. Create a new function and name it based on the function's intention (name it based on what it does, rather than how it is named)
Even if you get together to extract (extract) code that is very simple, for example, just a message or a function call, as long as the name of the new function can better demonstrate the code intent, you should also extract it, but if you don't think of a name that is more deliberate, don't change it.
2. Copy the extracted code from the source function to the new target function.
3. Check the extracted code carefully to see if the scope is referenced, which is limited to the variables of the source function (including local variables and source function parameters ).
4. check whether there are temporary variables (teemporary variables) that are common to the extracted code. If so, declare it as a temporary variable in the target function.
5. Check the extracted code to see if the value of any local-scope variables is changed. If a temporary variable value is modified, check whether the extracted code can be processed as a query and assign the result to the relevant variable. If it is difficult to do this, or if there are more than one modified Variable, you cannot just extract the code from the original, you may need to use Split Temporary Variable first. Then try to extract it. You can also use Replace Temp with Query to eliminate the temporary variables.
6. Pass the local variables to be read in the extracted code as parameters to the target function.
7. Compile after processing all local variables.
8. In the source function, replace the extracted code with (call the target function)
If you move any temporary variables to the target function, check whether they are outside the extracted code. If so, you can delete them now.
Example (Examples)
1. No Local Variables)
View sourceprint? 01 public class Extract
02 {
03 public void PrintUserInfo ()
04 {
05 Console. WriteLine ("******************************");
06 Console. WriteLine ("************** user information **********");
07 Console. WriteLine ("******************************");
08 string Name = "spring yang ";
09 string Age = "26 ";
10 string Sex = "Man ";
11 Console. WriteLine (string. Format ("name is {0}, age is {1}, sex is {2}", Name, Age, Sex ));
12}
13}
Changed:
View sourceprint? 01 public class Extract
02 {
03 public void PrintUserInfo ()
04 {
05 PrintStart ();
06 string Name = "spring yang ";
07 string Age = "26 ";
08 string Sex = "Man ";
09 Console. WriteLine (string. Format ("name is {0}, age is {1}, sex is {2}", Name, Age, Sex ));
10}
11
12 public void PrintStart ()
13 {
14 Console. WriteLine ("******************************");
15 Console. WriteLine ("************** user information **********");
16 Console. WriteLine ("******************************");
17}
18
19}
2. There is a Local variable (Using Local Variables)
If it is so simple, where is the difficulty of This refactoring technique? Yes, it is a local variable, including the parameters passed into the source function and the temporary variables declared by the source function. The scope of local variables is limited to source functions. So when I use the Extract Method, I have to spend extra time processing this variable. Sometimes they may even impede me, so that I cannot perform This refactoring at all.
The simplest condition for local variables is that the extracted Code only reads the values of these variables and does not modify them. In this case, I can simply pass them as parameters to the target function. We are faced with the following functions:
View sourceprint? 01 public class Extract
02 {
03 public void PrintUserInfo ()
04 {
05 string Name = "spring yang ";
06 string Age = "26 ";
07 string Sex = "Man ";
08 Console. WriteLine (string. Format ("name is {0}, age is {1}, sex is {2}", Name, Age, Sex ));
09 Console. writeLine (string. format ("{0} both year is {1 }. ", Name, DateTime. now. addYears (-int. parse (Age ))));
10}
11}
Changed:
View sourceprint? 01 public class Extract
02 {
03 public void PrintUserInfo ()
04 {
05 string Name = "spring yang ";
06 string Age = "26 ";
07 string Sex = "Man ";
08 PrintInfo (Name, Age, Sex );
09}
10
11 public void PrintInfo (string Name, string Age, string Sex)
12 {
13 Console. WriteLine (string. Format ("name is {0}, age is {1}, sex is {2}", Name, Age, Sex ));
14 Console. writeLine (string. format ("{0} both year is {1 }. ", Name, DateTime. now. addYears (-int. parse (Age ))));
15}
16}
If a local variable is an object and the extracted code calls a function that will cause modification to the object, it can also be processed as follows. Similarly, you only need to pass this object as a parameter to the target function. You must take other measures only when the extracted code really assigns a value to a local variable.
3. assign a value to the local variable (Reassigning)
If the extracted Code assigns values to local variables, the problem becomes complicated. Here we only discuss the problem of temporary variables. If you find that the parameter of the source function is assigned a value, you should immediately use Remove Assignments to Parameters.
View sourceprint? 01 public class Extract
02 {
03 public void PrintSum ()
04 {
05 double Result = 0;
06 for (int I = 0; I <= 100; I ++)
07 Result + = I;
08 Console. WriteLine ("From 1 add to 100 result is