Java敏捷开发技巧之消除代码异味

发表于:2011-9-28 09:33

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:yongbing    来源:51Testing软件测试网采编

分享:

  如果以后要支持更多的形状,这些类又要改动……,这可不是什么好事情!

  理想情况下,我们希望当一个类,一个方法或其他的代码设计完以后,就不用再做修改了。它们应该稳定到不用修改就可以重用。

  现在的情况恰好相反!

  每当我们增加新的形状,都得修改Shape这个类,跟CADApp里面的drawShapes方法。

  怎么让代码稳定(也就是无需修改)?这个问题是个好问题!不过老规矩,先不说,我们以行动回答。

  我们先看看另外一个方法: 当给你一段代码,你怎么知道它是稳定的?

  怎么判断代码的稳定性?

  要判断代码的稳定性,我们可能会这样来判定:先假设一些具体的情况或者需求变动了,然后来看一看,要满足这些新的需求,代码是否需要被修改?

  可惜,这也是一件很麻烦的事,因为有那么多的可能性!我们怎么知道哪个可能性要考虑,哪些不用考虑?

  有个更简单的方法,如果发现说,我们已经第三次修改这些代码了,那我们就认定这些代码是不稳定的。这个方法很“懒惰”,而且“被动”!我们被伤到了,才开始处理状况。不过至少这种方法还是一个很有效的方法。

  此外,还有一个简单,而且“主动”的方法:如果这段代码是不稳定或者有一些潜在问题的,那么代码往往会包含一些明显的痕迹。正如食物要腐坏之前,经常会发出一些异味一样(当然,食物如果有异味了,再怎么处理我们都不想吃了。但是代码可不行。)。我们管这些痕迹叫做“代码异味”。正如并不是所有的食物有异味都不能吃了,但大多数情况下,确实是不能吃了。并不是所有的代码异味都是坏事,但大多数情况下,它们确实是坏事情!因此,当我们感觉出有代码异味时,我们必须小心谨慎的检查了。

  现在,我们来看看上面例子中的代码异味吧!

  示例代码中的代码异味:

  第一种异味:代码用了类别代码(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;
}

62/6<123456>
重磅发布,2022软件测试行业现状调查报告~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2023
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号