Rebuilding notes -- replace functions with function objects and replace notes Functions
This article is in the study of the summary, welcome to reprint but please note the Source: http://blog.csdn.net/pistolove/article/details/42549977
In the previous article, we introduced "removing the parameter value". This article will introduce the refactoring method of "replacing functions with function objects.
Let's learn about This refactoring method.
Open door
We found that you have a large function. The use of local variables makes it impossible to use the refactoring method of "extract function.
Solution: Put the function into a separate object. In this way, the local variable becomes the object field, and then the large function can be decomposed into multiple small functions in the same object.
// Refactor the class Order... double price () {double basePrice; double secondaryPrice; double thirdaryPrice; // compute () ......} <
// After reconstruction, class Order... double price () {return new PriceCalculator (this ). compute ();} class PriceCalculator {double basePrice; double secondaryPrice; double thirdaryPrice; double compute (){//...}}
Motivation
In the previous article, we have been emphasizing the beauty and beauty of small functions. As long as the relatively independent code is extracted from a large function, it can greatly improve the readability of the Code.
However, the existence of local variables increases the difficulty of function decomposition. If local variables in a function are flooded, it is very difficult to break down the function. The "replace temporary variables with queries" method can help relieve the burden, but sometimes it is still impossible to disassemble a function. In this case, we should consider using function objects. The reconstruction method in this article will convert all local variables into the fields of the function object. Then, you can use the "extract function" to create new functions and reduce the size of the original large functions.
Practice
(1) create a new class and name it based on the purpose of the function to be processed. (2) create a final field in the new class to save the object where the original large function is located. For each temporary variable and parameter of the original function, create a corresponding field to keep it in the new class. (3) create a constructor in the new class to receive all parameters of the original function as the parameters of the original object. (4) create a compute () function in the new class. (5) copy the code of the original function to the compute () function. To call any function of the source object, use the original object field. (6) Compile and test. Because all local variables are now fields, you can break down this large function without passing any parameters.
Example
Let's start with the following example:
class Account{int gamm(int value, int quantity, int year2Date){int importValue1 = (value * quantity) + delta();int importValue2 = (value * year2Date) + 200;if(year2Date - importValue1 >200)importValue2-=50;int importValue3 = importValue2 * 8;//......return importValue3 - 2 * importValue1;}//.....}
To change this function to a function object, you must first declare a new class. The final object is provided in the new class to save the original object. Each parameter and temporary variable of the function are also retained with one field.
class Gamm{private final Account _account;private int value;private int quantity;private int year2Date;private int importValue1;private int importValue2;private int importValue3;
Next, add a constructor.
Gamm(Account source, int inputVal, int quantity, int year2Date){this._account = source;this.value = inputVal;this.quantity = quantity;this.year2Date = year2Date;}
Now you can move the original function to compute. The _ account field must be used in any part of the function that calls the Accout class.
int compute(){importValue1 = (value * quantity) + _account.delta();importValue2 = (value * year2Date) + 200;if(year2Date - importValue1 >200)importValue2-=50;importValue3 = importValue2 * 8;//......return importValue3 - 2 * importValue1;}
Then, modify the old function and let it delegate the work to the newly completed function object.
int gamm(int value, int quantity, int year2Date){return new Gamm(this,value,quantity,year2Date).compute();}
The above are the basic principles of the reconstruction method in this article. The benefit is that you can now easily extract functions from the compute () function without worrying about parameter passing.
// Use the extract function without worrying about parameter issues int compute () {importValue1 = (value * quantity) + _ account. delta (); importValue2 = (value * year2Date) + 200; importantThing (); importValue3 = importValue2 * 8 ;//...... return importValue3-2 * importValue1;} private void importantThing () {if (year2Date-importValue1> 200) importValue2-= 50 ;}
This article mainly introduces the refactoring method-replacing functions with function objects. We do not like the method with a large number of temporary variables, which will only confuse us. For functions with many local variables, it is necessary to use the reconstruction method described in this article to convert them into function objects. In this way, the temporary variables are converted into the fields of function objects, you can then perform other reconstruction methods. Finally, I hope this article will help you. If you have any questions, please leave a message. Thank you. (PS: the next article will introduce refactoring notes-replacement algorithm)
Rebuild note articles as follows
Rebuild notes-getting started
Rebuilding notes-bad taste of code (I)
Rebuilding notes-bad taste of Code (Part 2)
Rebuilding notes -- Building a test body
Rebuilding notes -- refining Functions
Rebuilding notes-inline functions
Refactoring notes-inline temporary variables
Rebuilding notes -- replacing temporary variables with queries
Refactoring notes -- Introducing explanatory variables
Rebuilding notes -- breaking down temporary variables
Refactoring notes -- remove the value assigned to the parameter