Reconstruction of bad code (a)

Code refactoring is not just finishing, it provides an efficient and controlled finishing code technology.

(A) Reconstruction of the Principle

1. What is reconstruction

A method of adjusting the internal structure of the software with the aim of changing the software without observable behavior, improving its understandability, modified to reduce its cost.

Another explanation is: the use of a series of reconstruction techniques, without changing the software observable behavior, adjust its structure.

2, why reconstruction

Improved software design: if there is no reconstruction, the design process will gradually deteriorate, much like the reconstruction is finishing the code, all you did was make everything should be back at the position.

Help find a bug: the code refactoring, code can be used as in-depth understanding, while figuring out the structure of the program, I do not want to kick out the bug is immune.

Improve programming speed: fast development of good design is fundamental to improve the design, readability, reduce errors, improve the quality of these are.

3, when reconstruction

In any case I am opposed to devote time to reconstruct. Reconstruction of things have never been a particularly should set aside time to do the reconstruction should be carried out anytime, anywhere.

Three law

The first is to do something just do it; the second will do something similar disgusted; the third time to do something like that, you should be reconstructed

The most common is to reconstruct the timing of adding new features to the software of the time;

Another driving force behind the reconstruction of one-is: the design code can not help me easily add features needed

Modify the wrong time, when the review of the code refactoring

And reconstruction of indirection

Computer science is a science: it is believed that all problems can be solved by adding a level of indirection.

Most refactoring introduces more indirection the program, the reconstructed object tend to split into a large number of small objects, the major function of the small split into a plurality of functions.

However, indirect layer is double-edged sword. Every time a put things into two, you will need to manage more than a thing. If an object delegate to another object, which commissioned another object, the program will be more difficult to read.

When not to reconstruct : Sometimes both the code is too confusing, it is better to re-write a reconstruction is more simple.

Rewrite rather than a clear signal is reconstructed: the existing code can not function properly.

(B) Code of bad taste

A duplicate code

If you see the same program structure in more than one location, you can be sure: try them combined, the program will become better.

The same class have the same expression: extract duplicate code, and then let the two places to call that piece of code is extracted out;

The two mutually brothers subclass contains the same expression: extract the same code, it pushes the deficit with class;

Appear in two unrelated classes: the repeated code to extract a separate class.

2, long class

Has a short function of the object outlive better, longer. Indirection can bring all the benefits - the ability to explain, sharing capabilities, the ability to choose - are supported by a small function.

Whenever feel the need to comment to explain something, we need to put things written description of a separate function.

How to determine which piece of code to extract? Comments are looking for a good technique. They can often be noted uses semantic distance between code and implement methods. If there is one line of code in front of the comment is to remind you: You can replace this code into a function.

Conditional expression and circulation is often refined signal.

3, too much class

If you want to use a single class to do too much, too often their inner strength variables will appear.
If there are too many in the class code is code duplication, confusion and ultimately to the source of disease deaths.

4, a long parameter list

The parameter list is too long is difficult to understand, too many parameters can cause inconsistencies, not easy to use, and once you need more data, you have to modify it. If the object is passed to the function, most of the changes will not be necessary.

5, changes divergent

If a class changes frequently occur for different reasons in different directions, then the time will probably be the object into two would be better that way each object can be possible because a change needs to be modified only.

6, modified formula shotgun

If you do not encounter some kind of change, you have to make a number of small modifications in many different classes, you are facing bad taste is the shotgun-style changes. If you need to modify the code spread around and you not only hard to find them, it is easy to forget some important changes.

All you need to modify the code into the same class, if at the moment there is no suitable class can be placed on the creation of a code.

7, Attachment Hunger

Object points are: the data and the operating behavior of the data packed together there is a classic scent is: a function of interest in a class higher than the interest of their own in which class. To calculate a value of a function from another object that calls the function value of almost half a dozen.

A function often used functions of several classes, then it is the place where? Our principle is: to determine which class has the largest data used by this function, the function and then put those data together.

8, Data mud pie

See the emergence of a lot of places with the same thirty-four data. These data are always tied together should have appeared objects of their own.

First, find a place that data appear as fields, will refine them into a separate object. Direct benefit of this is that many parameters can be simplified to shorten the column function call.

9, the basic type paranoid

A great value that the object: they blur the boundaries between the large cross-once type and volume of basic data

Novice object technology are often reluctant to use small objects on small tasks - combined with the value and proportion of the money class, there is a start and end values ​​of a range of classes. The separate existence of the original value of the replacement as an object, and thus out of the traditional caves, into the hottest objects in the world.

10, switch thriller coming out

Object-Oriented is a most striking feature: a switch statement to see less switch statement, it should be considered polymorphic to replace it.

If only some selected instances in a single function, and does not want to change them, then polymorphism is a bit overkill.

11, parallel to the integrated system

Every time you add a subclass to a class, another class must also be a corresponding increase in a subclass.
The general strategy is to eliminate this repetitive: Let a system of inherited instance reference to an instance of another inheritance hierarchy.

12, the redundancy

Originally a class worthy of its own worth, but it reconstructed stature diminished, no longer do so much work, this time to let go of this class solemn sense of it.

13, the future of rhetoric

Attempt to hook a variety of special situations and to deal with some non-essential things, this appeared pregnant with taste. If you use a worthwhile, if less than it is not worth it, just in your way, so it pushed to it.

If you have an abstract class that actually does not play much role in the function of some parameters on the use ... you can not remove them.

14, temporarily confusing field

An instance variable of only a specific set of circumstances. This makes the code easy to understand. Speculation had set purpose in the case of unused variables, it makes you crazy.

15, over message link coupling

If you see the user requests an object to another object, another object and then to the latter request, then a request for further objects ...... .. This is a message chain. In this way, it means that the client code will look closely coupled with the process of the navigation structure. Once any change in the relationship between objects occurs, the client will have to make the appropriate changes.

16, middleman

Packaging is often accompanied by the delegate. You might see half of a class interface functions are delegated to other classes, so that excessive use.

17, Xiani relations

Sometimes you see two classes are too close, too many calls time to explore each other's private component. Too Xiani class must break up, help them to draw the line, thereby reducing Xiani acts.

Inheritance is often caused by excessive intimacy, as a subclass of understanding of the superclass is always more than the latter's subjective desire. If you feel that your child live independently, let him leave inheritance.

18, similar to the class

Both functions do the same thing, but has a different signature.

19, imperfect library

Library function construction is not good enough, you can not modify them:

If only one or two classes of function modification, additional functions can be introduced. If you want to add a lot of extra behavior, create a new class that contains these additional acts make this subclass.

20, data classes childlike

Childlike data category refers to: they have a number field, and a function for access (read and write) of these fields, in addition to a belongings.

  • Package public field;

     

  • Appropriate wrapper class field;

     

  • Removing function should not be modified set of fields;

     

  • Refining call the function to hide the value / set value of the function;

     

21, rejected the bequest

Subclass only use a portion of the functions and data of the parent class. The establishment of a sibling class is a subclass, all less than a field / move to the next sibling class function, to ensure ultra pure class;

22, excessive comments

Comment exists because the code is very bad. The highest level of comments - the code that is annotated.

When you feel the need to write a comment, please try to reconstruct, to try to make all comments are superfluous.

(C) the re-organization function

1, refining function

Motivation: see function or a long period of comment is required in order to make people understand the purpose of the code, put this code in a separate function;

 

Practice : to create a new function, according to the intention of this function to name it;

As long as the name of the new function can clear intent of the code in a better way, you should also refine it. But if you can not think of a more meaningful name do not move

The rendering code is copied from the original function to the new objective function;

Code segment to be refined and local variables need to be read, as a parameter to the objective function;

In the source function, the code will be replaced refining segment as the objective function call.

2, inline

Body and the name of a function equally clearly understood. Insert body function call point function, the function is then removed.

Motivation: a group of organizations is not reasonable function. You can inline them all into one big function, and then extract the tissue from which a reasonable small functions.

Indirection too much use, so that all functions in the system are entrusted to another seems simple function, resulting in confusing between the commission action.

practice:

1, the check function is determined not to have the polymorphism;

If the subclass inherits this function, we do not use this inline function, because the subclass can not rewrite a function does not exist.

2, find all points calling this function;

3, all points calling this function are replaced by a function of the body.

3, inline temporary variables

There is a temporary variable is assigned only once with a simple expression, but it prevents other reconstruction techniques.

All references to the variables of the operation, replacement with the expression that temp
Double basePrice anOrder.basePrice = ();
return (Base> 10000);

Replace with:

return (anOrder.basePrice > 1000);

4, to replace the temporary variable query

Your program to a temporary variable to hold the result of a calculation expression. This expression to extract a separate function. All this temporary variable reference point is replaced with a call to the new function. Since then, new functions can be other functions use.

double basePrice = quantity * timePrice;
if(basePrice > 1000){
   return basePrice * 09.5;
} else {
   return basePrice * 0.98;
}

Replace with:

if(basePrice() > 1000){
   return basePrice * 09.5;
} else {
   return basePrice * 0.98;
}
double basePrice(){
   return quantity * timePrice;
}

Temporary variable is visible only if the variable is replaced by a temporary query function belongs, then with all functions in a class will get copies of this information, which will bring you great help, you can make for this class to write cleaner code.

5, the introduction of variable comment

Do you have a complex expression. The result of a complex expression (or part) is placed in a temporary variable expression in order to explain the use of the variable name.

if ((platform.toUpperCase().indexOf("MAC") > -1) && (browser.toUpperCase().indexOf("IE") > -1) && wasInitialized() && resize >0){
   //do smothing
}

Replace with:

final boolean isMacOs = platform.toUpperCase().indexOf("MAC") > -1;
final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") > -1;
final boolean wasResized = resize >0;
if(isMacOs && isIEBrowser && wasInitialized() && wasResized){
   //do smothing
}

Expressions can be very complex to understand. In this case, the temporary variable expression can help you be broken down into more manageable form.

In conditional logic, you can use this clause to reconstruct the conditions of each extracted to a temporary variable to explain the significance of good naming the corresponding condition clause. Another situation is: the longer the algorithm, you can use a temporary variable to explain the significance of each step of the operation.

6, decomposition temporary variables

Your program has a temporary variable is assigned more than once, it is neither a loop variable nor be used to collect the results. For each assignment, create a separate, temporary variables corresponding.

double temp = 2 * (height + width);
System.out.println(temp);
temp = height * width;
System.out.println(temp);

Replace with:

double perimeter = 2 * (height + width);
System.out.println(perimeter);
double area = height * width;
System.out.println(area);

If the temporary variable is assigned more than once, it means that they bear responsibility in more than one function.

If the temporary variable to assume more responsibility, it should be replaced by a number of temporary variables. Each variable only bear a responsibility, with a temporary variable to assume two different things will make the code reader confused

7, remove the assignment of parameters

A copy of the code parameters. In a position of the temporary variable substitution parameter.

int discount (int inputVal, int quantity, int yearToData){
   if(inputVal > 50) inputVal -= 2;
}

Replace with:

int discount (int inputVal, int quantity, int yearToData){
   int result = inputVal;
   if(inputVal > 50) result -= 2;
}

If the semantic code is passed by reference, please call after call to check whether the segment also uses this parameter.

8, replacement algorithm

Want to replace an algorithm is another algorithm clearer. The other function is to become body replacement algorithm.

String foundPerson(String[] people){
   for(int i = 0;i < people.length; i++){
       if(people[i].equals("Don")){
           return "Don";
       }
       if(people[i].equals("John")){
           return "John";
       }
       if(people[i].equals("Kent")){
           return "Kent";
       }
   }
   return "";
}

Replace with:

String foundPerson(String[] people){
   List candidates = Arrays.asList(new String[]{"Don", "John", "Kent"});
   for(int i = 0;i < people.length; i++){
       if(candidates.contains(people[i])){
           return prople[i];
       }
   }
   return "";
}

(D) move the object between the characteristic

In the object design process, the decision on where the responsibility is, if not the most important thing, is one of the most important things.

Often using only move function and simply move an object moving field behavior, we can solve these problems. If these two reconstruction techniques need to be used, I will move first to use the field, then use the move method.

If a class took on too much responsibility and become bloated, it will be used to extract the class in this case to separate out the part of the responsibility. If a class becomes too irresponsible, using the class into which the inlined into another class.

1, move function

Your program, there is a function of a class with one another through the exchange and outside of it in classes: call the latter or the latter call. The establishment of a new function has a similar behavior of the function longest referenced class. The old function into a mere delegate function, or to completely remove the old function.

If a class has too many acts, or if a class with another class there are too many of cooperation and highly coupled, we need to move the function. The system may be simpler class

2, move fields

Program, a field used by another class more than they are in the class. Create a new field in the target class, modify the original field of all users, so that they use the new field

3, refining class

A class done should be done by the two sort of thing. Create a new class, from the relevant fields and functions on the class moved to a new class.

4, the class inlined

A class does not do too much, not enough to assume responsibility for some reason that there is no longer alone. All properties of this class moved to another class, then remove class.

5, hide "trust relationship"

Customers to call another object by a delegate class. Establish all functions required by customers in the service class, used to hide the trust relationships.

Packaging means each object should be less about other parts of the system. Once changed, you need to understand this change of subject will be relatively small.

If a customer to get the service object to another object through a field, and then call the latter function. Then the customer must be aware of this layer trust relationships. In case of trust relationships change, customers must change accordingly.

6, removing the middleman

A simple class to do too much commission. Allow customers to directly call the delegate class.

Whenever the customer to use the new features hands delegate class, you must add a simple delegate function on the server. As commissioned by the characteristics of the class more and more, this process will make you very painful.

7, the introduction of additional functions

You need to add a function to provide class of service, but you can not modify this class. Build a client function in the class and pass an instance of the first class service parameters form.

Date newStart = new Date(year, month, date + 1);

Replace with:

Date newStart = nextDay(nowDate);
private static Date nextDay(Date arg){
   retrun new Date(arg.getYear(), arg.getMonth(), arg.getDate() + 1);
}

If you can modify the source code, you can add a new function on their own; if not, you have a client code, complement the function you want

8, the introduction of local expansion

You need to provide some additional functions for the service class, but you can not modify this class. Create a new class, so that it includes these additional functions. Let this be a source of product extensions subclass or wrapper classes.

(E) reorganize the data

1, since the packaging field

Direct access to a field. Establishing the value / set value function of this field, and only the field to access these functions.

private int low, high;
boolean includes(int arg){
   retrun arg >= low && arg <= high;
}

Replace with:

private int low, high;
boolean includes(int arg){
   retrun arg >= getLow() && arg <= getHigh();
}
int getLow(){
   retrun low;
}
int getHigh(){
   return high;
}

On the "field access mode" this issue, there are two very different perspectives:

  • In the class definition where the variable, you are free to visit.

     

  • Even in this class, you should also use the access functions only indirect access.


Indirect benefits of access are: sub-class of access to data can be changed by rewriting a function; it supports more flexible data management, such as lazy initialization.

2, instead of the data values ​​in the object

Do you have a data item, use makes sense in conjunction with other data and behavior. The data item becomes the object.

In the beginning you will be willing to use a string to represent the concept of "telephone number", but then you will find phone numbers need to "Format" and act "area code" and the like. This time it is necessary for the new category value of the replacement belt.

3, the value of the referenced object to the object

You derived from a class equal to each other many instances, it is desirable to replace them with the same object. This value becomes the object referenced objects.

4, the reference value of the object to the object

Do you have a reference object, small and can not be changed, and difficult to manage. Turn it into a value object.

5, to replace the array objects

You have an array of elements each represent different things. To replace an array of objects. For each element in the array to a field to represent

6. Copy "is monitoring data"

You have some exposure to the field of data GUI controls, functions and areas need to access the data. Copying the data to a field object. Observer establish a pattern for synchronization is repeated and the data objects within the field of the GUI object.

7, the association changed to one-way bidirectional associations

Both classes require the use of other features, but only during a one-way connection. Add a reverse pointer, modify and update the two functions can be simultaneously connected.

8, the bidirectional association changed to one-way association

There are two-way association between two classes, but now no longer need a class characteristics of another class. Remove unnecessary association.

9, to replace the magic number literals

Do you have a literal value, with a special meaning. Create a constant, according to its significance to name it, and replace the literal value of the above-mentioned constants.

10, the package field

There is a public field in your class. Declare it as private, and provide access functions.

11, the package collection

There is a function that returns a collection. Let this function returns a read-only copy of the collection, and provide add / remove function set of elements in this class.

(F) simplify the conditional expression

1, decomposition of the conditional expression

There is a complex conditional statements. From if, then, else extracted three paragraphs each function independently.

2. Consolidated expression

You have a series of test conditions, all get the same result. These tests will be combined into a conditional expression, and this conditional expression distilled into a separate function.

3, the combined duplicate of the condition code

On each branch expressions are performed the same piece of code. This code is repeated to move out of the conditional expression.

4, the control flag is removed

In a series of Boolean expressions, a variable with the role of "Control Mark". At break / return statements substituent control flag.

5, to replace the conditional expression polymorphic

There is a conditional expression to choose a different behavior depending on the type of object. Each branch of the conditional expression into the overwrite function within a subclass, and the original function is declared as abstract function

(Vii) a simplified function calls

1, the function was renamed

It failed to reveal the name of the function of their use. Modify the function name.

2, add the parameter

A function needs more information from the calling end. Adds an object parameter for this function, so that only the required information function of the target band.

3, remove parameters

No longer need a body function parameters. Removal parameters.

4, separation of functions and modify the query function

A function not only returns the object state value, and modify the object values. Create two different functions, one of which is responsible for querying the other for modification.

5, so that the function parameters carry

Some do similar work function, but containing a different value in the function body. Creation of a single function, parameter to express those different values.

There are two such functions: they are doing similar work, but few value resulting behavior is slightly different.

In this case, you may be separated from each of these functions the same together, and to process those parameter changes, to simplify the problem.

6, to replace the clear function parameters

Do you have a function, which depends entirely on the behavior of different parameter values. For each possible value of the parameter, the establishment of an independent function.

If a parameter has a variety of possible values, and in turn conditional expressions within the function to check these parameter values ​​and make different behavior depending on the parameter values, then you should use this term reconstruction.

7, keeping intact the object

Some values ​​taken from an object, when they are used as a parameter of a function call. Instead pass an entire object.

8, to replace the function parameters

A function call to the object, and the results are passed as a parameter to another function, and to accept the arguments of the function itself of a function can be called. Let the recipient parameters to remove this parameter, a function called directly before.

9, the introduction parameter object

Some parameters are always naturally occur simultaneously. These parameters are substituted to an object.

10, the value of the function set is removed

Class is set in a field value when the object is created, and then no longer be changed. Remove all set values ​​of the attributes of function.

11, hidden functions

A function that has never been used in any other category. The function is changed to private.

12, a factory substituted constructor function

We do not just want a simple construction of the action when you create the object. The constructor function replaced with the factory.

(Viii) treatment generalization relationship

1, the shift field

Two subclasses have the same field. The field is moved to the superclass.

2, the shift function

Some functions produce identical results in each sub-category. The function to move the superclass.

3, the shift constructor body

Respective subclasses have nearly identical number constructor body. Create a constructor in the superclass, and call it in a subclass constructor.

4, function down

Superclass of a function only with some (but not all) sub-category used. The correlation function into subclasses.

5, the field down

Superclass of a field is only used in part (but not all) sub-class. The field required to move its subclasses.

6, refining subclass

Some characteristics of the class is only some (but not all) instances used. A new subclass, the characteristic of the portion moved subclass.

7, refining superclass

Both classes have similar characteristics. For both classes to create a super class, super class will move to the same characteristics.

8, refining Interface

Several customers use the same subset of the class interface, or an interface, the same two portion. The same subset of a separate interface to extract.

9, the folding system inheritance

No big difference between the superclass and subclasses. Combine them into one.

10, create a template function

Subclass some functions similar operation is performed in the same order, but slightly different details of the operations. The operation into separate function (signature remains the same), and then move them to the superclass.

11, in order to entrust to replace inheritance

A subclass uses only a portion of the superclass interface or no inherited data. New sub-class field holds the superclass, subclass adjustment function delegate superclass, cancel inheritance.

12, to inherit replace commission

You use trust relationships in two classes, and often commissioned to write a lot of very simple function for the entire interface. `Let delegate class inherits fiduciary class.

Guess you like

Origin www.cnblogs.com/xingxia/p/code_better.html