Code refactoring (i): function refactoring rules

Source: Internet
Author: User

Refactoring is something that must be done after the project is done to a certain extent. Code refactoring can improve existing code design and enhance the extensibility and maintainability of existing projects. As the needs of the project continue to iterate and the requirements are constantly being updated, the code we write in the project is always changing. In a new requirement, you add some feature modules, but these feature modules may not be available for the next requirement. Or you need to iterate and change your original method or class to become bloated, and the coupling between each module or hierarchy increases. At this point, you have to consider refactoring.

Refactoring, in the classic book "Refactoring, improving the design of existing code," gives the definition, presumably, to modify the internal characteristics of the code without altering the external performance of the code. To be blunt, our test cases are the same, and then we modify the structure of the existing code. Refactoring is often encountered in software development and is also very important. You can refactor your existing code in demand iterations, Debug,code review.

In the next few posts, I would like to take a peek at the beauty of code refactoring and learn some of the rules of code refactoring. Of course there is a small demo in every rule, and the blog in this blog and related content is implemented using swift language. Of course, as with design patterns, refactoring is important in terms of techniques and ideas, and the use of what language is not very relevant. Classic refactoring books are implemented using the Java language, and if you are familiar with other languages such as PHP, Python, and so on, you can use these languages to test some refactoring techniques.

The topic of this blog is to reconstruct the existing functions or methods that need to be reconstructed through some column reconstruction techniques. And each sample is shared on GitHub, and a small partner of interest can download it. Some small partners said, I do not have a Mac, how to write your swift code to compile it? This is a good problem to solve, you can read the blog I published earlier, " spy on Swift's use of the Web browser to compile swift code and the generics in Swift ." You can copy the relevant code and observe the results in the browser. Because the Web site compiled online is foreign, there may be some lag in access, but can be used. Okay, so much for the front, to get into today's theme.

Directory:

First, the large function by the module split into several small functions

Second, the trivial small function through the integration of the inline

Replace some temporary variables with functions (substitute a temporary variable with a function query)

Iv. splitting complex expressions into multiple expressions (splitting complex expressions with multiple explanatory temporary variables)

Splitting temporary row variables with different meanings under different semantics

Vi. removing the assignment of a function parameter (introducing another temporary variable)

Vii. replacing functions with objects

Extract Method (extract function )-------split large functions into several small functions by module

Extract method is translated into Chinese is the meaning of the extraction function, which is used in code refactoring very much. In refactoring, it is advocated to subdivide the code module, because the smaller the module, the greater the degree of reusability. Do not write large functions, if your function is too large, then this means that your function needs to be refactored. Because the function is too large, maintainability, the understanding will become worse. And when you implement similar functions, it's easy to generate duplicate code. When writing code, the most taboo is the code duplication. This is what is often called the DRY (Don ' t Repeat yourself) principle. So when the function is too long, you need to subdivide it and split the original function into several functions.

Below will be an example to intuitively feel the extract Method, of course, these examples are not my original, is "refactoring: Improve the design of the existing code" in the Java example of the evolution of the swift version, when writing the SWIFT code, the original example of some modifications, is pseudo-original bar. But there is only one purpose: to communicate and share with you. There is no need to find other examples to illustrate these refactoring rules, because refactoring: improving the design of existing code is really too classic.

1. The code that needs refactoring is shown below. There are two constant attributes in the MyCustomer class in the code below, and the class provides a constructor. The class also provides an output method, that is, the first property in the class to print instructions, in fact, there is no function in the class.

  

After writing a class that requires refactoring, we'll write a test case for that class. This makes it easy to verify the correctness of the refactoring as we refactor, because every refactoring is done to make sure that we refactor correctly. Below is the test case written for the example above and the printed result of the test case. Of course, after refactoring we also need to invoke the test case and see if the print results are consistent with the previous. Of course, if you don't want to see for yourself, you can add unit tests for the classes above, which are often used in regular projects. As for adding test cases, we'll cover them in more detail later in the blog. Below is the test case and output of the above class:

2. Next we analyze the printowning function in the above class. The above class can work correctly, which is for sure. But the printowning () function is not well written. Because it does too much work, which means that the function includes other submodules that need to be split. As you can see from the red box in the screenshot above, each red box represents a separate function module, which means that this piece of code can be split into separate functions. When splitting a molecular function, we need to make a name that matches the function of the code block. This means that when you see the name of the function, you should know what the function is doing.

The code snippet below is our refactoring class. White, is the function can be independent of the module to extract, and for the extraction of the new function of a suitable name. After refactoring, the printowing () function has only two lines of code, so it is easy to understand the function name in which it is called. The three functions that are split below are also a separate module because the functions are short, so they are easy to understand and easy to reuse. After extract Method, of course, the benefits are many. After refactoring the code, I call the above test cases, the output and the original code is always, if inconsistent, then you have a problem with refactoring, you need to debug.

Two. Inline method----Inline function: Integrate trivial small functions

See "Zhouyi" of small partners should all know, "Zhouyi" expressed in the thought of a point is "extremes meet". The "Nine" (sixth-digit Yang Yao) or "six" (sixth-extremes meet) of each of the 64-gua in the book of Zhouyi is a manifestation of the act. In fact, "Zhouyi" is actually computer science in the binary representation, because Taiji born two (2 in the 2), the two instrument four elephant (2 square is 4), four elephant gossip (4 x 2 = 8), gossip has evolved 64 gua. The 64-Gua is the 0-1 arrangement in 2 binary. 95 Extreme, 96 is extremes meet. Wo Kao, pull away, of course, this refers to "Zhouyi" is not to say how to use Zhouyi how to Suangua, how to predict, this baby does not believe this thing. But the philosophy in the book of Zhouyi is still necessary to learn. Some take, do not take.

Back to the topic of this blog, the Inline method is actually relative to the extract method. When you are refactoring or programming, the module is over-encapsulated, that is, using extract method a bit too much, the too simple to encapsulate things, such as a simple Boolean expression, and the expression has been used only once. This is the excessive use of extract method performance. Extremes meet, so we need to neutralize with the inline method, put the overly encapsulated function back in, or put back the functions that are not necessarily encapsulated. That is the opposite of extract method.

As for the example of the inline method rule, there is not much to repeat here, because you only need to flip the example of extract method.

Three. Replacetemp with query---- Replace the temporary variable with a query: replace some temporary variables with functions

1.Replace temp with Query It's plain to say that temporary variables that have complex expressions assigned and used more than once are replaced with query functions, meaning that the value of the temporary variable is obtained by the function's return value. This allows complex temporary variables to be reused when implementing functions of a similar function, thus reducing the repetition rate of the code. Below is a specific demo of the Replace temp with query rule, which we will then use to refactor with the replace temp with query rule for the GetPrice () function.

It is not necessary to create a corresponding test case for the small demo above, because we will test the consistency of my refactoring code based on the test case, and below that is the test case and output of the code, as shown below.

2. The next step is to analyze and refactor the GetPrice () function in the Procut class. There is a Baseprice temporary constant in the first red box in the GetPrice () function, which has a more complex assignment expression that we can refactor using replace Temp with query, which is to create a function that returns the value of the expression. The discountfactor temporary variable in the second red box is used multiple times, and we can refactor it through the Replace Temp with query rule, as shown in the following refactoring code.

It is easy to see from the refactoring code that the temporary constants or variables we mentioned above do not exist, instead of two query methods, and the corresponding query method returns the values of the temporary variables or constants that were previously eliminated.

Iv.Inline Temp---Inline temporary variable: opposite to replace temp with query above

When a temporary variable is assigned only by a simple expression, the temporary variable interferes with other refactoring techniques. At this point, we should not use replace Temp with Query. Sometimes we use the inline temp rule because of the excessive use of the replace temp with query rule, or extremes meet, when using the replace temp with query, you need to use the inline Temp is fixed, and of course the example of the inline temp is the opposite of replace temp with query, so there's not much to repeat.

V.introduce explaining Variable--- introduction of explanatory variables: splitting complex expressions into multiple variables

When there is a more complex expression in a function, we can split the expression into different variables according to the function. The split expression is more readable than an expression that was not previously split. Split the expression into the appropriate temporary variable, that is, introduce explaining Variable, if the temporary variable is used multiple times, we can also try to use the Replace temp with query rule to remove the temporary variable, That is, the temporary variable is replaced with a query function.

1. A long expression is returned in the GetPrice () method in the product class below, at first glance the function feels very uncomfortable. Because it returns an expression that is too long and not very readable. In this case, it is necessary to split the expression.

2. Next you can use the introduce explaining variable rule to introduce explanatory variables. As the name implies, the variables we introduce are intended to explain the functionality of a part of the expression, in order to make the expression more readable. With the introduce explaining variable rule, it is equivalent to adding a corresponding comment to the expression. Below is the result of refactoring using the introduce explaining variable rule.

3. The temporary variable is introduced for readability, and if the expression represented by the temporary variable is used more than once, we can refactor the above function using the Replace Temp with query rule. That is, to remove the temporary variables that are often used and complex expressions, the following snippet is the replace temp with query refactoring for the above function, removing the temporary variable, and the result of the re-refactoring is as follows.

Six,split temporary Variable----- Decomposition temporary variables: The heart is not two-use

What is called decomposition of temporary variables, specifically, is in a function of a temporary variable can not do two things, that is, a temporary variable can not be assigned to a different meaning value. If you do this, then I'm sorry, please break down the temporary variable that is reused, that is, you need to create a new temporary variable to receive the value assigned to the first temporary variable for the second time, and to make an exact name for the second temporary variable.

The first function below is refactored, and you can see that temp is repeatedly assigned a value of two times, if the two values are not related, and temp is not sufficient to describe the meaning of the two values. Then it means that the code should be refactored. Of course, refactoring is also very simple, only need to specialize in the operation of the industry, each of its own duties, and for each temporary variable to a suitable name. The practice is shown below.

 

Remove Assignments to Parameters---- Removing the assignment of parameters

What does "remove the assignment of a parameter" mean? As the name implies, do not assign values to function parameters in the function. This means that you do not assign values to the function's parameters in the scope of the function (except, of course, the input and output parameters), and when you modify the parameters of the function directly, I am sorry, you should refactor this at this time. Because this will be the original value of the parameter is missing, we need to introduce a temporary variable, and then the temporary variable to operate.

1. The discount () function below does not work well because the non-inout parameter inputval is modified and returned directly in the discount () function, which we do not recommend. In this case, we need to refactor the function below using the Remove Assignments to parameters rule.

2. The refactoring technique is also particularly simple, which is to replace the inputval using the temporary variable of the function, which is the reconstructed function below.

Eight.Replace method with method object---- Replace function with function object

When a very long function, and the function contains more complex temporary variables, using those methods are not good for refactoring, we have to consider encapsulating the function as a class. The object of this corresponding class is the function object. We can turn the arguments in the field function and the temporary variables into the properties of the class, and the function should do things as a method of the class. After transforming a function into a function class, we can use some of the above methods to refactor the functions in the new class. See the example below for specific practices.

1. The discount function in the example below has too many parameters (of course, there are more parameters than this in real-world project engineering), and the function contains multiple temporary variables, assuming that the function is more complex and relatively long. The following example reconstructs the function using those rules above, so that we can abstract the function into a class.

2. The first step in refactoring is to abstract the above discount () function into the discount class. There are six properties in the discount class, and these six properties correspond to the different parameters of the discount () function, respectively. In addition to adding parameter properties, we added a delegate agent object to the account when the function class was fetched. The delegate agent object is to access the data that is dependent on the account class in the discount class, followed by the first refactored code.

3. Next, we can refactor using the rules described above in the compute () method in the new discount class. Analyzing the Compute () method, we found that properties such as Importandvalue can be eliminated by the replace Temp with Qurey rule. We can reconstruct the above method once again, and the concrete code after refactoring is as follows:

Today's blog focuses on how to refactor functions in existing code, and 8 rules are mentioned in this blog post. These 8 rules are very useful and very important in the refactoring of function code. Still, the code is implemented using swift, but the code refactoring is not about thinking and language. Next you will continue to update the blog about code refactoring, so please look forward to it.

Code refactoring (i): function refactoring rules

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.