Refactoring notes--moving functions

Source: Internet
Author: User

This article is in the study summary, welcome reprint but please specify Source: http://blog.csdn.net/pistolove/article/details/42679983


We all know that classes tend to become bloated because they take on too much responsibility. In this case, it is common to use the "refinement class" approach to separate part of the responsibility. If a class becomes "irresponsible", it is generally used in an "inline class" approach to incorporate it into another class. If a class uses another class, it is generally helpful to use the "hide-and-trust" approach to hide the relationship. Sometimes hiding a delegate relationship can cause the owner's interface to change frequently, and then consider using the "remove middleman" approach.

The refactoring technique of the "Move between Objects" series is introduced from the beginning of this article . This paper introduces the reconstruction technique of "moving function".

Let's learn this refactoring technique.


straight to

Discovery: There is a function in the program that communicates more with another class than its resident class.

Workaround: Create a new function with similar behavior in the class that the function most commonly refers to. Turn the old function into a simple delegate function or completely remove the old function.


Motive

"Moving function" is one of the most important features in the reconstruction theory. In general, if a class has too many behaviors, or if one class has too much co-operation with another class to form a high degree of coupling, then the function should be moved. In this way, the classes in the system can be made simpler, and these classes will eventually be more cleanly implemented for the tasks of system delivery.

In the process of development, I will occasionally explore all the functions of the class, looking for such a function: It uses another object more times than the number of its own objects. Once some fields have been moved, such checks should be performed. Once it is discovered that it is possible to move a function, it observes the end of the call, the end of its invocation, and any of its redefined functions in the inheritance system. It then determines its moving path based on "more communication between the function and the Read object".

Things are often not so easy to make a decision. If you are not sure whether you should move a function, you should continue to observe other functions. Moving other functions often makes this decision easier. Sometimes, even if you move other functions, it is difficult to make a decision about the current function. If it is really difficult to make a decision, then perhaps moving the function or not is not important. Then, let it stay there, anyway, it can always be modified.


Practices
(1) Examine all the attributes used by the original function in the original class, including the fields and functions, and consider whether they are also moved. (2) Check the subclass and superclass of the original class to see if there are other declarations for the function. (3) Declare this function in the target class. (4) Copy the Code of the original function into the target function. Adjust the latter to allow it to function properly in the new home. (5) Compile the target class. (6) Decide how the target object should be correctly referenced from the original function. (7) Modify the original function so that it becomes a purely delegate function. (8) compile, test. (9) Decide whether to delete the original function, or to preserve it as a delegate function. (10) If the original function is to be removed, all calls to the original function in the original class are replaced with the call to the target function. (11) compile, test.

Example
we are from an account class that represents "accounts"Start:
Class Account {private accounttype _type;private int _daysoverdrawn;double overdraftcharge () {if (_type.ispremium ()) { Double result = 10;if (_daysoverdrawn > 7) result + = (_daysoverdrawn-7) * 0.85;return result;} else {return _daysoverdrawn * 1.75;}}}
       Now suppose there are several new accounts, each with its own "overdraft amount billing rule", so we want to move the Overdraftcharge () function into the AccountType class.
first, you need to observe each feature that is used by Overdraftcharge () and consider whether it is worthwhile to move them with the Overdraftcharge () function. In this example, we keep the _daysoverdrawn field in the account class because this value changes with different kinds of accounts. Then, copy the Overdraftcharge () function into the accounttype and make the appropriate adjustments.
Class AccountType {double overdraftcharge (int daysoverdrawn) {if (Ispremium ()) {Double result = 10;if (Daysoverdrawn > 7) Result + = (daysOverdrawn-7) * 0.85;return result;} else {return daysoverdrawn * 1.75;}}}
       in the example, the meaning of "adjustment" is: (1) for the use of accounttype characteristics of the statement, remove _type, (2) to find a way to get the account class characteristics still needed. When you need to use the original class, there are four options: (a) Move this feature to the target class, generally to its member variable, (b) Establish or use a reference relationship from the target class to the original class, (c) Pass the original object to the target function as a parameter, (d) If the desired attribute is a variable, pass it as a parameter to the target function. In this example, the _daysoverdrawn variable is passed as an argument to the target function. after adjusting the target function, compile, then you can replace the function body of the original function with a simple delegate action, and then compile and test.
Class Account {Double Overdraftcharge () {return _type.overdraftcharge (_daysoverdrawn);}
       you can preserve the styles that your code already has, or you can delete the original function. If you want to delete the original function, you need to find out all the callers and redirect the caller to the Bankcharge () of the account.
Class Account {Double Bankcharge () {Double result = 4.5;if (_daysoverdrawn > 0) result + = _type.overdraftcharge (_daysove Rdrawn); return result;}}
       after all the call points have been modified, the declaration of the original function in account is deleted. It can be compiled and tested after each deletion, and can be done in batches at once, but it needs to be particularly careful. If the removed function is not private, you also need to check if the other class is using the function. because the removed function in this example only refers to a field, you simply pass the field as a parameter to the row. If the removed function calls another function in the account, this is not a simple process. In this case, the original object must be passed to the target function.
Class AccountType {Double Overdraftcharge (account account) {if (Ispremium ()) {Double result = 10;if (account.getdaysoverd Rawn () > 7) Result + = (Account.getdaysoverdrawn ()-7) * 0.85;return result;} Else{return account.getdaysoverdrawn () * 1.75;}}
       In some cases, multiple attributes of the original class are required, and the original object is passed to the target function. However, if the target function requires too many primitive class attributes, further refactoring is required. Typically, the target function is decomposed and some parts are moved back to the original class.


This paper mainly introduces the reconstruction technique--the moving function. We will often use this refactoring technique, especially when we find that a parametric function is not only applicable to the current class, but also to other classes, so that the function can be extracted as a separate function into the tool class for other classes to be used in the same situation. Finally, I hope this article will be of some help to you. There are questions to leave a message, thank you. (PS: The next article will introduce refactoring notes--moving fields)

The refactoring Note article is as follows

Refactoring Notes-Introductory article

Refactoring notes-bad taste of code (UP)

Refactoring notes-bad taste of code (bottom)

Refactoring notes-building a test body

Refactoring notes-Refining functions

Refactoring notes-inline functions

Refactoring notes-Inline temporary variables

Refactoring notes-replacing temporary variables with queries

Refactoring notes-Introduction of explanatory variables

Refactoring notes-breaking temporary variables

Refactoring notes-Removing the assignment of parametersRefactoring notes--moving functions



Refactoring notes--moving functions

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.