AP计算机科学A(APcomputer science A)复习备考攻略视频教程
42753 人在学
现在,我们来看看上面例子中的代码异味吧!
示例代码中的代码异味:
第一种异味:代码用了类别代码(type code)
class Shape {
final int TYPELINE = 0;
final int TYPERECTANGLE = 1;
final int TYPECIRCLE = 2;
int shapeType;
...
}
这样的异味,是一种严肃的警告:我们的代码可能有许多问题。
第二种异味:Shape这个类有很多属性有时候是不用的。例如,radius这个属性只有在这个Shape是个圆的时候才用到:
class Shape {
...
Point p1;
Point p2;
int radius; //有时候不用
}
第三种异味:我们想给p1,p2取个好一点的变量名都做不到,因为不同的情况下,它们有不同的含义:
class Shape {
...
Point p1; //要取作“起始点”,“左下点”,还是“圆心”?
Point p2;
}
第四种异味:drawShapes这个方法里面,有个switch表达式。当我们用到switch(或者一大串的if-then-else-if)时,小心了。switch表达式经常是跟类别代码(type code)同时出现的。
现在,让我们将这个示例中的代码异味消除吧!
消除代码异味:怎么去掉类别代码(type code)
大多数情况下,要想去掉一个类别代码,我们会为每一种类别建立一个子类,比如(当然,并不是每次要去掉一个类别代码都要增加一个新类,我们下面的另一个例子里面会讲另一种解决方法):
class Shape {
}
class Line extends Shape {
Point startPoint;
Point endPoint;
}
class Rectangle extends Shape {
Point lowerLeftCorner;
Point upperRightCorner;
}
class Circle extends Shape {
Point center;
int radius;
}
因为现在没有类别代码了,drawShapes这个方法里面,就要用instanceof来判断对象是哪一种形状了。因此,我们不能用switch了,而要改用if-then-else:
class CADapp {
void drawShapes(Graphics graphics, Shape shapes[]) {
for (int i = 0; i < shapes.length; i++) {
if (shapes[i] instanceof Line) {
Line line = (Line)shapes[i];
graphics.drawLine(line.getStartPoint(),line.getEndPoint());
} else if (shapes[i] instanceof Rectangle) {
Rectangle rect = (Rectangle)shapes[i];
graphics.drawLine(...);
graphics.drawLine(...);
graphics.drawLine(...);
graphics.drawLine(...);
} else if (shapes[i] instanceof Circle) {
Circle circle = (Circle)shapes[i];
graphics.drawCircle(circle.getCenter(), circle.getRadius());
}
}
}
}