【Effective Java】条20:类层次优于标签类

标签类,这里指类依据本身的某个属性,来确定类会产生不同的对象。很明显,这不符合类的单一职责原则。如:

public class Figure {

  enum Shape {
    RECTANGLE, CIRCLE
  }

  private Shape shape;

  /** rectangle fields*/
  private double length;
  private double widht;

  /** circle fields*/
  private double radius;

  /** constructor for circle*/
  Figure(int radius) {
    this.radius = radius;
  }

  /** constructor for rectangle*/
  Figure(int length, int width) {
    this.length = length;
    this.widht = width;
  }

  double area() {
    switch (shape) {
      case RECTANGLE:
        return length * widht;
      case CIRCLE:
        return Math.PI * radius * radius;
      default:
        throw new AssertionError();
    }
  }

}

以上代码表示,类Figure拥有lengthwidthradisshape属性,且当shapeRECTANGLE的时候,只使用lengthwidth属性,当shapeCIRCLE的时候,则使用radius属性。这里属性shape就相当于标签,用于区分类的不同。

由于设计不符合单一职责原则,那我们按如下步骤进行重构:
1. 在标签类中选取依赖于标签的方法,提取作为抽象类的共同方法。这里就是area()方法。

public abstract class AbstractFigure {
  public abstract double area();
}
  1. 新建继承于抽象类的子类,并将特定标签相关的属性及方法移到该子类中。在这里,比如说当shapeCIRCLE时,特定相关的就是属性radius及构造方法。
public class CircleFigure extends AbstractFigure {

  private double radius;

  public CircleFigure(double radius) {
    this.radius = radius;
  }

  @Override
  public double area() {
    return Math.PI * radius * radius;
  }
}

public class RectangleFigure extends AbstractFigure {

  private double length;
  private double width;

  public RectangleFigure(double length, double width) {
    this.length = length;
    this.width = width;
  }

  @Override
  public double area() {
    return length * width;
  }
}

猜你喜欢

转载自blog.csdn.net/xl890727/article/details/80332677