代码改变世界

Effective Java 20 Prefer class hierarchies to tagged classes

2014-03-15 09:56  小郝(Kaibo Hao)  阅读(355)  评论(0编辑  收藏  举报

Disadvantage of tagged classes

1. Verbose (each instance has unnecessary irrelevant fields).

2. Error-prone (Program will fail by initializing wrong fields).

3. Inefficient (Memory footprint is increased for not used field).

   

/**

* Tagged class - vastly inferior to a class hierarchy!

* @author Kaibo

*/

class Figure {

enum Shape {

RECTANGLE, CIRCLE

     };  

// Tag field - the shape of this figure

final Shape shape;

// These fields are used only if shape is RECTANGLE

double length;

double width;

// This field is used only if shape is CIRCLE

    double radius;  

// Constructor for circle

Figure(double radius) {

shape = Shape.CIRCLE;

this.radius = radius;

}

// Constructor for rectangle

Figure(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();

}

}

}

   

/*

* Refined with Hierarchies

*/

/**

* Class hierarchy replacement for a tagged class

 

* @author Kaibo

 

*/

abstract class Figure {

abstract double area();

}

   

public class Rectangle extends Figure {

// specific fields

final double length;

final double width;

Rectangle(double length, double width) {

this.length = length;

this.width = width;

}

   

/*

* Common methods

 

* @see com.effectivejava.classinterface.Figure#area()

*/

@Override

double area() {

return length * width;

}

}

   

public class Circle extends Figure { 

/**

* specific fields.

*/

final double radius;

Circle(double radius) {

this.radius = radius;

}

/*

* common method

* @see com.effectivejava.classinterface.Figure#area()

*/

@Override

double area() {

return Math.PI * (radius * radius);

}

}

Summary

If you're tempted to write a class with an explicit tag field, think about whether the tag could be eliminated and the class replaced by a hierarchy. When you encounter an existing class with a tag field, consider refactoring it into a hierarchy.