异味这个词,可能有点抽象,我们先看一下下面的例子。
这是一个CAD系统。现在,它已经可以画三种形状了:线条,长方形和圆。先认真的看一下下面的代码:
class Shape { final static int TYPELINE = 0; final static int TYPERECTANGLE = 1; final static int TYPECIRCLE = 2; int shapeType; //线条的开始点 //长方形左下角的点 //圆心 Point p1; //线条的结束点 //长方形的右上角的点 //如果是圆的话,这个属性不用 Point p2; int radius; } class CADApp { void drawShapes(Graphics graphics, Shape shapes[]) { for (int i = 0; i < shapes.length; i++) { switch (shapes[i].getType()) { case Shape.TYPELINE: graphics.drawLine(shapes[i].getP1(), shapes[i].getP2()); break; case Shape.TYPERECTANGLE: //画四条边 graphics.drawLine(...); graphics.drawLine(...); graphics.drawLine(...); graphics.drawLine(...); break; case Shape.TYPECIRCLE: graphics.drawCircle(shapes[i].getP1(), shapes[i].getRadius()); break; } } } } |
代码都是一直在改变的,而这也是上面的代码会碰到的一个问题。
现在我们有一个问题:如果我们需要支持更多的形状(比如三角形),那么肯定要改动Shape这个类,CADApp里面的drawShapes这个方法也要改。
好,改为如下的样子:
class Shape { final static int TYPELINE = 0; final static int TYPERECTANGLE = 1; final static int TYPECIRCLE = 2; final static int TYPETRIANGLE = 3; int shapeType; Point p1; Point p2; //三角形的第三个点. Point p3; int radius; } class CADApp { void drawShapes(Graphics graphics, Shape shapes[]) { for (int i = 0; i < shapes.length; i++) { switch (shapes[i].getType()) { case Shape.TYPELINE: graphics.drawLine(shapes[i].getP1(), shapes[i].getP2()); break; case Shape.TYPERECTANGLE: //画四条边. graphics.drawLine(...); graphics.drawLine(...); graphics.drawLine(...); graphics.drawLine(...); break; case Shape.TYPECIRCLE: graphics.drawCircle(shapes[i].getP1(), shapes[i].getRadius()); break; case Shape.TYPETRIANGLE: graphics.drawLine(shapes[i].getP1(), shapes[i].getP2()); graphics.drawLine(shapes[i].getP2(), shapes[i].getP3()); graphics.drawLine(shapes[i].getP3(), shapes[i].getP1()); break; } } } } |