Three measures to improve the reusability of Java code

Source: Internet
Author: User
Three measures to improve the reusability of Java code-general Linux technology-Linux programming and kernel information. The following is a detailed description. This article introduces three methods for modifying existing code to improve reusability. They are: modifying the instance method of the class, changing the parameter type to the interface, and selecting the simplest parameter interface type.

Measure 1: rewrite the instance method of the class

Implementing code reuse through class inheritance is not an accurate code reuse technology, so it is not the best mechanism for code reuse. In other words, if we do not inherit all methods and data members of the entire class, we cannot reuse a single method in the class. Inheritance always leads to redundant methods and data members, which always complicate the code of a method in the reuse class. In addition, the dependency of a derived class on the parent class further complicate the code: Changes to the parent class may affect the subclass. When you modify any class in the parent class or subclass, it is hard to remember which method covers the quilt class and which method does not cover the quilt class. Finally, it is not obvious whether the override method in the subclass needs to call the corresponding method in the parent class.

Any method, as long as it executes a single concept task, itself should be the preferred reusable code. To reuse this code, we must return to the process-oriented programming mode and remove the class instance method from the global process. To improve the reusability of this process, the process code should be written like a static tool method: it can only use its own input parameters, but can only call other global processes, you cannot use any non-local variables. This restriction on external dependencies simplifies the application of the process, allowing the process to be conveniently used anywhere. Of course, because this type of organization always gives the Code a clearer structure, even code that does not consider reusability can also benefit from this.

In Java, methods cannot exist independently from classes. To this end, we can organize related processes into independent classes and define these processes as public static methods.

For example, for the following class:
Class Polygon {
.
.
Public int getPerimeter (){...}
Public boolean isConvex (){...}
Public boolean containsPoint (Point p ){...}
.
.
}

We can rewrite it:
Class Polygon {
.
.
Public int getPerimeter () {return pPolygon. computePerimeter (this );}
Public boolean isConvex () {return pPolygon. isConvex (this );}
Public boolean containsPoint (Point p) {return pPolygon. containsPoint (this,
P
);}
.

}

PPolygon is:
Class pPolygon {
Static public int computePerimeter (Polygon polygon ){...}
Static public boolean isConvex (Polygon polygon ){...}
Static public boolean
ContainsPoint (Polygon polygon, Point p ){...}
}

The class name pPolygon shows that the encapsulation process of this class is mainly related to objects of the Polygon type. P in front of the name indicates that the only purpose of this class is to organize the public static process. In Java, a class name that starts with a lowercase letter is a non-standard method, but a class like pPloygon does not actually provide the functionality of a common Java class. That is to say, it does not represent a class of objects. It is only a mechanism for Java to organize code.

In the above example, the final effect of modifying the code is to make the customer code that applies the Polygon function no longer need to inherit from Polygon. The Polygon class function is now provided by the pPolygon class in process units. The Customer Code only uses the code you need, and does not need to care about the features you do not need in the Polygon class. But it does not mean that the role of classes has been weakened in this new procedural programming. On the contrary, classes play an indispensable role in the process of organizing and encapsulating object data members, and as described in the following section, multi-interface Implementation of polymorphism also brings excellent support for code reuse. However, because encapsulating code functions using instance methods is not the preferred method of code reuse, It is not ideal to achieve code reuse and polymorphism support through class inheritance.

Measure 2: Change the parameter type to the interface

As Allen Holub pointed out in Build User Interfaces for Object-Oriented Systems, the main point of code reuse in Object-Oriented Programming is to use polymorphism through interface parameter types, instead of using class inheritance:

"…… Code reuse is achieved through interface rather than class programming. If all the parameters of a method are references to some known interfaces, this method can operate on such objects: When we compile the method code, the classes of these objects do not even exist. Technically, the reusable method is not the object passed to the method ."

Apply the Holub's opinion on the result of "Measure 1". When a block of code can be written as an independent global process, you only need to change all its class-form parameters to interface-form parameters, we can further improve its reusable capabilities. After this change, the parameters of the process can be the objects of all classes implementing the interface, not just the objects created by the original class. As a result, the process can operate on a large number of possible object types.

For example, suppose there is a global static method:
Static public boolean contains (Rectangle rect, int x, int y ){...}

This method is used to check whether the specified vertex is included in the rectangle. In this example, the rect parameter type can be changed from the Rectangle class to the interface type, as shown below:

Static public boolean contains (Rectangular rect, int x, int y ){...}

The Rectangular interface is defined as follows:

Public interface Rectangular {Rectangle getBounds ();}

Now, all the objects created for a class that can be described as a rectangle (that is, the class that implements the Rectangular Interface) can be used as the rect parameter provided to pRectangular. contains. By relaxing the parameter type restrictions, we can make the method more reusable.

However, for the above example, if the getBounds method of the Rectangular interface returns Rectangle, you may doubt whether it is really worthwhile to do so. In other words, if we know that the object in the input process will return a Rectangle when called, why not directly pass in the Rectangle to replace the interface type? The most important reason for not doing so is the collection. Let's assume that there is such a method:

Static public boolean areAnyOverlapping (Collection rects ){...}

This method is used to check whether any rectangular objects in a given set overlap. Inside this method, when we use a loop to access each object in the Set in turn, if we cannot convert the object cast into an interface type such as Rectangular, how can we access the rectangular area of an object? The only choice is to convert the object cast into its unique class form (we know it has a method that can return a rectangle), which means that the method must know the object type it operates on in advance, so that the reuse of methods is limited to those object types. This is the problem that the previous measure tries to avoid first!

Measure 3: select the simplest parameter interface type.

When implementing the second measure, which interface type should be used to replace the given class form? The answer is which interface fully meets the parameter requirements of the process and has the least redundant code and data. The simpler the interface required to describe the parameter object, the larger the chance for other classes to implement this interface-the more classes the object can use as the parameter. This can be easily seen from the following example:

Static public boolean areOverlapping (Window window1, Window window2 ){...}

This method is used to check whether two windows (assuming a rectangular window) overlap. If this method only requires obtaining the rectangular coordinates of two windows from the parameters, it is better to simplify the two parameters accordingly:

Static public boolean areOverlapping (Rectangular rect1, Rectangular rect2)
{
...}

The above Code assumes that the Window type implements the Rectangular interface. After modification, We can reuse the function of this method for any rectangular object.

Sometimes there may be too many methods for interfaces that describe parameter requirements. At this point, we should define a new public interface in the global namespace for other code that faces the same problem to reuse.

When we need to use a parameter like a function pointer in C, it is the best choice to create a unique interface to describe the parameter. For example, assume that the following process exists:
Static public void sort (List list, SortComparison comp ){...}

This method uses the comparison object comp provided in the parameter to compare the object sorting list in the given list. The only requirement of sort for the comp object is to call a method for comparison. Therefore, SortComparison should be an interface with only one method:
Public interface SortComparison {
Boolean comesBefore (Object a, Object B );
}

The only purpose of the SortComparison interface is to provide a hook for sort, so the SortComparison interface cannot be reused elsewhere.

All in all, the three measures in this document are suitable for transforming existing code written in accordance with object-oriented conventions. These three measures are combined with the Object-Oriented Programming Technology to obtain a new code writing technology that can be used in later coding. It can simplify the complexity and dependency of the method, at the same time, the reusable capability and internal cohesion of methods are improved.

Of course, the three measures here cannot be used for code that is inherently unsuitable for reuse. Code that is not suitable for reuse usually appears at the presentation layer of the application. For example, the code used to create a program user interface and the control code linked to the input event all belong to the code that is very different between the program and the program. This code is almost impossible to duplicate.
Related Article

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.