庄生晓梦

庄生晓梦迷蝴蝶

博客园 首页 新随笔 联系 订阅 管理
  • 标签类:其中有许多样板代码,包括枚举声明,标签域和条件语句
  • 如果要给它添加风格,除了有权限修改源码之外,你还得给每个条件语句都添加一个条件,否则就会在运行时失败
  • 标签类过于冗长,容易出错,并且效率低下
  • 我们可以用类层次类代替标签类 – 子类型化
public class Figure {
    enum Shape{RECTANGLE,CIRCLE};

    final Shape shape;

    double width;
    double length;

    double radius;

    Figure(Double radius){
        shape = Shape.CIRCLE;
        this.radius = radius;
    }

    Figure(double width,double length){
        shape = Shape.RECTANGLE;
        this.width = width;
        this.length = length;
    }

    double area(){
        switch(shape){
            case RECTANGLE:
                return width*length;
            case CIRCLE:
                return Math.PI*(radius*radius);
            default:
                return 0;
        }
    }
}

如何将一个标签类优化为类层次 – 子类型化
1.为标签类中的每个方法都定义一个包含抽象方法的抽象类,这些方法的行为都依赖于标签值
2.为每种原始标签类都定义根类的具体子类
Figure类对应的类层次

/**
 * 子类型化:定义能表示多种风格对象的单个数据类型,标签类是对其的一种效仿
 */
public abstract class Figure {
    abstract double area();
}

public class Circle extends Figure {
    final double radius;

    Circle(double radius) {
        this.radius = radius;
    }

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

}

public class Rectangle extends Figure {

    final double length;
    final double width;

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

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

最后扩展:类层次可以用来反映类型之间本质上的层次关系,有助于灵活性,并且进行更好的编译检查
如:正方形本质上也是一种矩形,在类中如何反应?

    public class Square extends Rectangle {

//  Square(double length, double width) {
//      super(length, width);
//      // TODO Auto-generated constructor stub
//  }
    Square(double side) {
        super(side, side);
    }
}

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

posted on 2017-03-05 01:31  qwop  阅读(232)  评论(0编辑  收藏  举报