Refactoring notes-Introducing local extensions

Source: Internet
Author: User

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


The introduction of an additional function is described in the previous article . This article will introduce the refactoring technique of "introducing local extension".

Let's learn this refactoring technique.



straight to

Discovery: You need to provide some extra functions for the service class, but you can't modify the class.

Workaround: Create a new class that contains these extra functions. Make this extension a subclass or wrapper class for the source class.



Motive

None of us can predict the future of a class, and they often fail to prepare some useful functions for you beforehand. If you can modify the source code, then it is very good, so you can directly add the functions you need. But you often can't modify the source code. If you only need one or two functions, you can introduce an additional function for processing. But if you need more than one function, it's hard to control them with an external function. So, we need to organize these functions and put them in a proper place. In order to achieve this goal, we need to use the sub-class and packaging of the two technologies. In this case, the handle class or wrapper class is collectively referred to as a local extension.

A local extension is a separate class, but it is also an extended subtype: it provides all the resource characteristics of the class while adding new features. In any place where you use the source class, you can use local extensions instead.

The use of local extensions makes it possible to adhere to the principle that functions and data should be uniformly encapsulated. If you keep the code that should be placed in the extension class scattered in other classes, it will eventually complicate the other classes and make it difficult to reuse the functions.

Choosing between subclasses and wrapper classes typically selects subclasses because the workload is smaller. However, the biggest obstacle to making subclasses is that it must be implemented early in the object creation. If you can take over the object creation process, of course, that's fine, but if you want to use the local extension after the object is created, there's a problem. In addition, the subclass scheme must also produce a subclass object, so that if there are other objects that reference the old object, then there are two objects that save the original data! If the original data is not modifiable, it can be safely copied, but if the modification is allowed, the problem will follow because a modification action cannot change two copies at the same time. In this case, you must use the wrapper class. When you use a wrapper class, changes to the local extension affect the original object, and vice versa.




Practices
(1) Create an extension class that acts as a subclass or wrapper class for the original class. (2) Add the transformation constructor to the extension class. (The so-called "transformation constructor" refers to the "accept the original object as a parameter" constructor)(3) Add a new feature to the extension class. (4) Replace the original object with the extension object as needed. (5) Move all the additional function versions defined for the original class into the extension class.

Example
let's take the date class in Java as an example. Java has provided the functionality we want, but many times we need to extend the date class before it arrives. The first thing to do is to use subclasses or wrapper classes. Subclasses are the more obvious way to do this:
Class Mydatesub extends Date{public mydatesub nextday () ... public int dayofyear () ...}
the wrapper class requires the use of a delegate:
Class Mydatewrap{private Date _original;}
        Example: Using subclassesFirst, create a mfdatesub class to represent "date" and make it a subclass of date:
Class Mydatesub extends Date
then, you need to work with the differences between the date and extension classes. The Mfdatesub constructor needs to be delegated to the date constructor:
Public mydatesub (String datestr) {super (DATESTR);}
now, you need to add a transformation constructor whose arguments are the objects of a source class:
Public mydatesub (Date Arg) {super (Arg.gettime ());}
You can now add new attributes to the extension class, and use the Remove function to move all the additional functions to the extension class. So:
Client class...private static date nextday (date arg) {//foreign method, should is on Datereturn new Date (Arg.getyear (), ARG . GetMonth (), arg.getdate () +1);}
After removal , it becomes:
Class mydatesub ... Date NextDay () {return new Date (GetYear (), GetMonth (), getDate () +1);}


Example: Using wrapper classesfirst, a wrapper class is declared, and when the wrapper class is used, the constructor is set differently from the previous one. Now the constructor will only perform a simple delegate action:
Class Mydatewrap{private Date _original;}
Public Mydatewrap (String datestr) {_original = new Date (DATESTR);}
The transformation constructor simply assigns its instance variable:
Public Mydatewrap (Date arg) {__original = arg;}
Next is a tedious task: providing a delegate function for all the functions of the original class. Only two functions are shown here:
public int getYear () {return original.getyear ();} public boolean equals (Object arg) {if (This==arg) {return true;} if (! ( Arg instanceof Mydatewrap) {return false;} Mydatewrap other = (mydatewrap) arg;return (_original.equals (other._original));}
after you have done this, you can move the date-related behavior to the new class using the Remove function. So:
Client class...private static date nextday (date arg) {//foreign method, should is on Datereturn new Date (Arg.getyear (), ARG . GetMonth (), arg.getdate () +1);}
after removal, there are:
Class Mydatewrap ... Date NextDay () {return new Date (GetYear (), GetMonth (), getDate () +1);}
There is a special problem with wrapper classes: How do I handle a function that accepts instances of the original class as arguments? For example :
public boolean after (Date Arg)
since the original class cannot be changed, I can only do it in one Direction-the After () function of the wrapper class can accept objects of the wrapper class or the original class, but the after () function of the original class can only accept the original class object and not the wrapper class object:
Awrapper.after (adate); Can is made to Workawrapper.after (Anotherwrapper); Can is made to Workadate.after (Awrapper); Not work
The purpose of this overwrite is to hide the existence of the wrapper class from the user. This is a good strategy because the user of the wrapper class really shouldn't carethe existence of a wrapper class should indeed be able to treat both the wrapper class and the original class. But I can't hide the existence of wrapper classes, because some system-provided functions(for example, Equals ()) will cause problems. You might think: Overwrite Equals () in the Mydatewrap class, like this:
public boolean equals (Date arg)//causes problems
        but it is dangerous to do so, and although it has achieved my purpose, the rest of the Java system thinks that equals () conforms to the Exchange law: if A.equals (b) is true, then b.equals (a) must be true. Violating this rule will make me suffer a lot of inexplicable mistakes. The only way to avoid this situation is to modify the date class. But why should I do this refactoring if I modify the date class? So, in this case, you can only expose the fact that "I'm packing" to the user. An equality check between dates will be performed with a new function:
public boolean equalsdate (Date Arg)      
You can overload equalsdate () so that one overloaded version accepts a Date object, and another overloaded version accepts the Mydatewrap object. This eliminates the need to check for unknown object types:
public boolean equalsdate (Mydatewrap Arg)   
There is no such problem in the subclass scheme, as long as the original function is not written. But if you overwrite a function in the original class, you'll be disoriented when looking for a function. Functions that overwrite the original class in a class are not normally extended, only new functions are added .


This paper mainly introduces the refactoring technique--introducing local expansion. This technique is relatively simple, easy to understand, here is not cumbersome. Finally, I hope this article will be of some help to you. There are questions to leave a message, thank you. (PS: The next section describes refactoring notes--reorganize functions)


Refactoring Note Articles

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-replacing functions with function objectsRefactoring notes--Replacement algorithmRefactoring notes--moving functions
Refactoring Notes-moving fieldsRefactoring Notes-Refining classes
Refactoring Notes-inline the class
Refactoring notes-hiding "delegate relationships"
Refactoring notes-removing middlemen       Refactoring Notes-introducing additional functionsRefactoring notes-introducing local extensions



Refactoring notes-Introducing local extensions

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.