[Refactoring learning] 09. Rebuilding function calls and 09 function calls
Previously, I wrote a function rebuild. Here I wrote a rebuild of the function call. The difference is that I want to write a function (or interface) that allows others to call well ).
1. rename a function
Modify point: the function name does not prompt the function purpose.
Method: Modify the function name.
If you want to write a comment to the function, you can write the comment as a name.
Martin's original words:
You may not be able to get a good name for the first time. At this time, you will think, that will be the case. After all, this is just a name.
Be careful. This is the call of the devil, the path to chaos, and never be tempted by it.
(I 've been tempted for countless times, and I 've got a lot of scum names, because it's really hard to think of a good name, unless I write the function name for a long time)
2. Add Parameters
Modify: A function needs to obtain more information from the caller.
Practice: add an object parameter to the function so that the object can bring all the information of the function.
3. Remove parameters (Well, compared to the second point, many people may be too troublesome to do this. The devil's temptation.)
Modification point: a parameter is no longer required for the function ontology.
Practice: Remove this parameter
4. Separate query functions from modify Functions(So simply use the property)
Modification point: a function returns the object status value and modifies the object status.
Practice: create two different functions, one of which is responsible for querying and modifying
There are exceptions, that is, the query and modification operations in concurrent scenarios, so you should still separate them, but write a function separately to perform these two tasks at the same time.
5. Make the function carry Parameters
Modification point: some functions do similar work, but they contain different values in the function ontology.
Practice: create a single function to express those different values with Parameters
Simply put, the two functions have many identical parts, and the values are different. If you use these values as function parameters, you can combine them into one.
6. Replace parameters with clear functions (Opposite to 5)
Change Point: You have a function, which takes different actions depending on the parameter value (optimistic is completely)
Practice: create an independent function for each possible value of this parameter.
This means that you take different actions based on the parameter judgment, so you can divide them into several functions for implementation.
If the impact is not great, use 5. If conditional judgment is required, use polymorphism to eliminate conditional judgment.
7. Keep the object complete
Modification point: you remove several values from an object and use them as parameters for a callback function call.
Practice: Pass the entire object
Motivation: in the future, if a function requires a new data item, you must search for and modify all calls to the function. This also improves the readability of the entire code.
But there are also exceptions: If you are wearing a value, the function depends only on the value, but if it is an object, it depends on the entire object, this may cause your structure to deteriorate, so you have to analyze the specific situation.
However, if a function uses a large number of values for another object, you may need to consider whether to place the function in the class to which the object belongs.
8. Replace parameters with functions
Modification point: the object calls a function and passes all results as parameters to another function.
Practice: Let the parameter receiver remove this parameter and directly call the previous function
Motivation: If the function can obtain the parameter value through other means, it should not obtain the value through the parameter. Too long parameter columns increase the programmer's understanding difficulty. Therefore, we should shorten the length of parameter columns as much as possible.
9. Introduce parameter objects
Modification point: Some parameters always appear at the same time.
Practice: replace these parameters with an object
I have already talked about where to refactor it, and other chapters seem to be involved. This type actually has other advantages. For example, if you have set up such a class, some functions may be put into this class to make the code structure clearer.
10. Remove the set function.
Modification point: a field in the class should be set as a value when the object is created, and then it will not be changed
Practice: Remove all the setting functions of this field.
That is to say, if you do not need to change a field during initialization, you should not add the setting function, which will make the intent ambiguous.
11. Hide Functions
Modification point: there is a function that has never been used by any other class.
Practice: change this function to private
Let the caller see what they should see and what they want to see. Do not expose too much information to them. The simpler the better, the more convenient they are to use and the more secure they are.
12. Replace constructors with factory Functions
Modify: You want to create an object instead of simply constructing it.
Practice: Replace the constructor with a factory function.
This is simple. In Data Reconstruction, my example is as follows.
public class Room { public Room() { } public static Room CreateRoom() { return new Room(); } }
This feature is used to remove type codes with polymorphism. It is particularly effective to remove too many conditional expressions.
That is, it is used to determine the Room type to create different sub-classes of the Room. Of course, if there are few types, you can add multiple factory functions to create different sub-classes respectively.
13. encapsulation downward Transformation
Modification point: the objects returned by a function must be transformed downward by the function caller.
Practice: Move the downward transformation action to the Function
Simple Example:
public class Room { public Room() { } public Object GetRandRoom() { return RoomList.GetRandRoom(new Random().Next()); } }
Should be converted
public class Room { public Room() { } public Room GetRandRoom() { return (Room)RoomList.GetRandRoom(new Random().Next()); } }
That is to say, some system functions or functions written by others return an object after processing. But you know that this object is of the Room type, Please convert it to the Room type, that is to say, we should try to transform at the underlying level, rather than at the call end. This increases the difficulty of the caller's understanding.
This situation may occur on the return iterator or set function.
But it looks like we. NET is almost never like this. At least I have never seen the code I have met. Is there too few code I have ever seen, or is it really amazing to everyone, avoiding this trap.
14. Replacing error codes with exceptions
Modify point: a function returns a specific code to indicate an error.
Practice: throw an exception instead.
Well, I don't need to talk about this. However, many people (including me) are used to returning error codes. Because it is simple, we encourage everyone to improve it.
By the way, yes. NET's error mechanism, that is, try catch finally throw, should be careful when it is used. There is a lot of controversy about this thing, that is, the exception you throw should be a controllable exception, the exception should not be unknown. If the exception is unknown, it should be resolved immediately, rather than swallowed up.
15. Replacing exceptions with conditional judgment
Modification point: in the face of conditions that a caller can check in advance, you throw an exception
Practice: Modify the caller so that the caller can check the caller before calling the function.
Well, this thing is to eliminate exceptions. That is to say, you can predict this exception in advance, and you should directly use some means to check the exception, if the check fails, the system returns the operation you performed after the catch operation. Instead of not checking, try catch directly. Frankly speaking, the fewer code in try catch, the better, because resources are required to locate exceptions.