25th: the number of function bodies cannot exceed 100
I remember seeing a function with more than 9000 rows in the past, which is spectacular. Since then, it is not surprising to see long functions. I think the main disadvantage of long functions is:
1. Serious ImpactCodeReading, where a variable is used may be separated by hundreds or even thousands of rows. If the IF-else has many nested layers, it will be even more nightmare.
2. It is not conducive to code reuse. Short and independent logic processing units are easier to reuse, while long code segments need to be further decomposed.
I think it is best for a function to have no more than 100 rows. For a function that is too long, it should be decomposed as much as possible. If it cannot be decomposed, it should be added through annotation.Description of the function processing steps, for example:
Public VoidFoo (){//1. verify the validity of parameters and internal states...//2. Start to tilt the angle...//2.1 calculation angle 1...//2.2 calculation angle 2...//3. Output computation statement...
}
26th: Use language modifiers to ensure that variables are non-mutable
When declaring a variable, if you are sure that the variable will not be modified or should not be modified, you 'd better declare it as immutable, for example, you can use the const modifier in final and C ++ in Java to prevent unexpected changes to the variable that should not be changed.
27th: Object State sharing
The existence of a large number of objects will occupy valuable memory of the system. If some of these objects are in the same State, you can extract these States to share all objects that require them, this can greatly reduce redundant objects to save memory. The flyweight mode in the design mode can solve this problem.
28th: replace common constants with objects
Since a normal constant is essentially a simple number or string, when we mistakenly use a constant of a category in another constant scenario, it will produce problems, however, the compiler does not prompt errors. Therefore, this may be a major risk, for example:
// Constant declaration indicating the user status Public Static Int User_state_active = 0 ; Public Static Int User_state_delete = 1 ; // Constant declaration of User Role Public Static Int User_role_normal = 2 ; Public Static Int User_role_manager = 3 ; // Determine whether the user is activated If (Userstate = User_role_normal ){}
This judgment should have used one of the two constants user_state_active and user_state_delete, but accidentally used other constants, which may not be found until the bug is generated.
Object constants can be used to avoid this situation, for example:
Public Class State { Private Int State; Public State (Int S) {state = S ;}} // Constant declaration indicating the user status Public Static State user_state_active = New State (0 ); Public Static State user_state_delete = New State (1 ); Public Class Role { Private Int Role; Public Role ( Int R) {role = R ;}} // Constant declaration of User Role Public Static Role user_role_normal = New Role (2 ); Public Static Role user_role_manager = New Role (3 );
The following judgment cannot be compiled because userstate is of the state type.
If(Userstate =User_role_normal ){}
29th: do not modify the query function
We generally judge the function based on the function name. functions with different tables may cause some problems, for example, we call a query function (the function that obtains the value of the member variable of the class): getname (), but it modifies the value of other member variables internally, when looking for the cause of a bug, it is very likely to ignore this function. From its name, I think it will not cause a problem. In the end, I find that it is a zombie, I guess I will scold the author of this function: his grandmother's code, such as his own, the table is different!
30th: Try to encapsulate the object creation process
As mentioned earlier, add the set and get functions for member variables as much as possible, the main purpose is to grasp the control of member variables. This is also true for the object creation process. If the provider has control over the object creation process, it can shield specific implementation classes, and any modification to the object creation process.