Valid Item 13-use tagged class with caution

Source: Internet
Author: User

In fact, the author's original title is <prefer class hierarchies to tagged classes>, that is, the class level is better than tagged class.



I don't know if there are any such statements about the tagged class. In fact, the author refers to a class that describes multiple abstractions and can decide different instances based on a field.

The following is an example in the book. Using Shape and some fields that represent the length to form a shape and calculate the area, the brain fills up what is tagged class:

class Figure {enum Shape {RECTANGLE, CIRCLE};// Tag field - the shape of this figurefinal Shape shape;// These fields are used only if shape is RECTANGLEdouble length;double width;// This field is used only if shape is CIRCLEdouble radius;// Constructor for circleFigure(double radius) {shape = Shape.CIRCLE;this.radius = radius;}// Constructor for rectangleFigure(double length, double width) {shape = Shape.RECTANGLE;this.length = length;this.width = width;}double area() {switch (shape) {case RECTANGLE:return length * width;case CIRCLE:return Math.PI * (radius * radius);default:throw new AssertionError();}}}


It is not difficult to see what information this class wants to convey, nor to see that such a method has many defects.

Although I can understand what it means, it is not readable because various implementations are crowded into a class.

Different implementations are described in a class. Different fields are used based on different implementations. That is, fields cannot be declared as final. (Is it necessary to process unnecessary fields in the constructor ?)

Although insignificant, memory usage is meaningless.

Summary: oo is not enough.



Although the previous article did nothing about the class hierarchy, the class hierarchy is actually used to solve this problem, and the above tagged class imitates the class hierarchy in a non-oo way.

To convert a tagged class into a class hierarchy, you must first abstract the behavior in the tagged class and provide it with an abstract class.

For example, we need a method named area.

Next we need to define a specific subclass for each tag, that is, the circle and rectangle in the example.

Then provide the corresponding field for the subclass, that is, the width and length of radius and rectangle in the circle.

Finally, we provide implementation of abstract methods for sub-classes.

In fact, we don't need to describe the conversion steps in this way, because oo itself is a natural thing.



The conversion result is as follows:

abstract class Figure {abstract double area();}class Circle extends Figure {final double radius;Circle(double radius) {this.radius = radius;}double area() {return Math.PI * (radius * radius);}}class Rectangle extends Figure {final double length;final double width;Rectangle(double length, double width) {this.length = length;this.width = width;}double area() {return length * width;}}class Square extends Rectangle {Square(double side) {super(side, side);}}


The benefits of doing so are obvious,

The code is simple and clear, and there is no sample code;

The types are independent of each other and will not be affected by irrelevant fields. The field can be declared as final.

Subclass rows can be expanded independently without interference.



Back to the initial tagged class, is it really useless?

If you use this class, you only need to use the corresponding parameters when calling the constructor to obtain the desired instance.

As in the Policy mode.

Of course, the tagged class may be regarded as a rule mode (passing behavior features rather than instance features), but the rule mode is not used in Java.



Generally, a policy specifies a specific behavior by passing functions by the caller.

But JAVA does not have function pointers, so we use object reference to implement the policy mode, that is, to call the method of this object.

For an object that serves only as a "carrier" of a method, that is, an instance equivalent to a method pointer, the author calls it a function object ).



For example, we have a concrete strategy ):

class StringLengthComparator {private StringLengthComparator() {}public static final StringLengthComparator INSTANCE = new StringLengthComparator();public int compare(String s1, String s2) {return s1.length() - s2.length();}}


A reference to a specific policy can be called a function pointer.

Abstract A specific policy into a strategy interface ).

In the preceding example, comparator is available in Java. util <t>:

public interface Comparable<T> {    int compare(T o1, T o2);        boolean equals(Object obj);}


Therefore, we may use an anonymous class to pass a specific policy:

Arrays.sort(stringArray, new Comparator<String>() {    public int compare(String s1, String s2) {        return s1.length() - s2.length();    }});



It seems that this is the case to use code description. I just passed a specific policy where I want to use it.

Disadvantage is obvious-you need to create an instance each time you call it.

But what can we do? After implementing the policy interface in a host class, every specific policy that may be used is made into a field and declared with final?

It seems silly, but it can be considered, because there are other benefits to doing so.

For example, a specific policy can have a more intuitive name than an anonymous class, and a specific policy can implement other interfaces.



The Code is as follows:

// Exporting a concrete strategyclass Host {    private static class StrLenCmp        implements Comparator<String>, Serializable {            public int compare(String s1, String s2) {                return s1.length() - s2.length();            }    }        // Returned comparator is serializable    public static final Comparator<String> STRING_LENGTH_COMPARATOR = new StrLenCmp();        ... // Bulk of class omitted}



(PS: corresponding to valid tive Java second edition item 20, 21)

This article is from the "alvez. Says: 99.9% 0b/S" blog, please be sure to keep this source http://alvez.blog.51cto.com/7711135/1531044

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.