类层次优于标签类

有时候,可能会遇到带有两个甚至更多风格的实例的类,并包含表示实例风格的标签(tag)域。
Demo:

 

[java]  view plain  copy
 
  1. // Tagged class - vastly inferior to a class hierarchy!  
  2. class Figure {  
  3.     enum Shape { RECTANGLE, CIRCLE };  
  4.   
  5.     // Tag field - the shape of this figure  
  6.     final Shape shape;  
  7.   
  8.     // These fields are used only if shape is RECTANGLE  
  9.     double length;  
  10.     double width;  
  11.   
  12.     // This field is used only if shape is CIRCLE  
  13.     double radius;  
  14.   
  15.     // Constructor for circle  
  16.     Figure(double radius) {  
  17.         shape = Shape.CIRCLE;  
  18.         this.radius = radius;  
  19.     }  
  20.   
  21.     // Constructor for rectangle  
  22.     Figure(double length, double width) {  
  23.         shape = Shape.RECTANGLE;  
  24.         this.length = length;  
  25.         this.width = width;  
  26.     }  
  27.   
  28.     double area() {  
  29.         switch(shape) {  
  30.           case RECTANGLE:  
  31.             return length * width;  
  32.           case CIRCLE:  
  33.             return Math.PI * (radius * radius);  
  34.           default:  
  35.             throw new AssertionError();  
  36.         }  
  37.     }  
  38. }  

这些标签类(tagged class)有着许多优点,但是破坏了可读性。
标签类过于冗长、容易出错,并且效率低下。

表示多种风格对象的数据类型:子类型化(subtyping)。标签类正是类层次的一种简单的仿效。
Demo:

[java]  view plain  copy
 
  1. // Class hierarchy replacement for a tagged class  
  2. abstract class Figure {  
  3.     abstract double area();  
  4. }  
  5. class Circle extends Figure {  
  6.     final double radius;  
  7.   
  8.     Circle(double radius) { this.radius = radius; }  
  9.   
  10.     double area() { return Math.PI * (radius * radius); }  
  11. }  
  12. class Rectangle extends Figure {  
  13.     final double length;  
  14.     final double width;  
  15.   
  16.     Rectangle(double length, double width) {  
  17.         this.length = length;  
  18.         this.width  = width;  
  19.     }  
  20.     double area() { return length * width; }  
  21. }  
  22. class Square extends Rectangle {  
  23.     Square(double side) {  
  24.         super(side, side);  
  25.     }  
  26. }  


标签类很少有适用的时候。当你想要编写一个包含显示标签域类时,应该考虑一下,这个标签是否可以被取消,这个类是否可以用类层次来代替。当你遇到一个包含标签与的现有类时,就要考虑将它重构到一个层次结构中去。

猜你喜欢

转载自windpoplar.iteye.com/blog/2316003