论坛首页 Java版 企业应用

项目心得-提高代码质量的体会(2)竟然不提示内容太多,直接截断!!

浏览 1347 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
时间:2007-05-22
 

1.1        Junit的引入

        Junit是当前十分流行的一个单元测试框架,实际上,junit只是java领域内的解决方案, 在其他领域junit所表达的这种测试理念,仍然是行得通的,而且有其他版本的实现,有兴趣的话大家可以去研究研究。在junit中包含了TestSuiteTestCase,都实现Test接口,看类的名字就可以明白suite是很多个case的集合,可以把case加入到suite中,让suite来启动。而对于每个TestCase也可以独立运行,这样的设计模式是很有意思的(这里我就不介绍了)。这例我就简单的实现一个junit单元测试:

java 代码
  1. Class ProcessTest extends TestCase{     
  2.      Processor p = new Processor();   
  3.      Public void testProcess(){     
  4.           int i = p.process( 1 );   
  5.           assertEquals( i,1 ); // 确保结果等于1,如果不等于1会抛出异常   
  6.           i = p.process( 2 );   
  7.           assertEquals( i,2 );   
  8.           i = p.process( 3 );   
  9.           assertEquals( i,0 );   
  10.      }   
  11. }   
  12.   

 

java 代码
  1. class Test {   
  2.         public TestSuite suite(){   
  3.                 TestSuite ts = new TestSuite();   
  4.                 ts.addTest( new ProcessTest() );   
  5.                 return ts;   
  6.         }   
  7. }   
  8.   

然后运行

测试结果产生了。还好在eclipse里面集成了Junit插件,开发起来非常简单,大家可以自己去研究研究,怎么用的问题我觉得已经超出了本文所要讨论的范围,而且如何使用junit进行单元测试也已经有人写出了书。

这样自己写单元测试对代码进行测试的过程叫白盒测试,因为程序员知道代码的内部结构,知道代码的条件分支,测试起来会比较测试人员来说覆盖率要高的多,也能提前发现问题,当一段代码经过单元测试之后,我终于可以松口气了。

下面给出一个比较简陋的单元测试的文档模版,该模版可以是简单的文本,或复杂的word表格甚至是excel都可以,基本包含的内容如下:

测试类

方法

参数

期望结果

实际结果是否和期望相符

时间

提交人

其他

DFBItem

GetItemById(int)

10

返回id10的对象

2006-

3-29

 

GetItemById()

0

Null

2006-

3-29

当进测试完成后,提交该文档,表示该功能完成开发可以提交使用了。当然,我对单元测试的经验也不是很丰富,一切都是想法,还要和大家经过探讨或者借鉴别人的经验才能获得更好的一些测试方法和测试文档。

还有一句名言:Keep the Bar Green to Keep the Code Clean(junit自带的测试工具里面有个滚动条,如果出错会显示红色,如果正确会显示绿色)

1.2        代码重构

“重构”是很早的时候听到的一个词,我觉得至少有1年的时间了。而且Martin Fowler也专门写了一本关于重构的书(和设计模式齐名的书!!看过一点,觉得很不错!)。实际上简单点的意思就是说对代码的重新组合,把代码放到需要它的地方去。这样可以提高代码重用率,提高效率。记得书里面将的第一个重构方法就是关于大块代码的(包括Big Class,Big Method等),大块代码不利于阅读,这是大家公认的事情,因此要对大块代码进行重新别写,分成很多个小的方法或类,方法越小,出错的机率也就小!

仍然来使用用户登录的例子,比如有个非常大的方法:

java 代码
  1. class User {   
  2.     //   
  3.     // loginType 包括   
  4.     // 0 普通登录   
  5.     // 1 身份锁登录   
  6.     // 2 单点登录   
  7.     public void login( String name,String pwd,int loginType ){   
  8.       if( loginType == 0 ){    
  9.           // 这里是处理普通登录的几十行代码   
  10.       } else if ( loginType == 1 ) {   
  11.           // 这是处理身份锁登录的几十行代码   
  12.       } else if ( loginType == 2 ) {   
  13.           // 这里是处理单点登录的几十行代码   
  14.       }   
  15.     }         
  16. }  

这样下来,

java 代码
  1. class User {   
  2.         //   
  3.         // loginType 包括   
  4.         // 0 普通登录   
  5.         // 1 身份锁登录   
  6.         // 2 单点登录   
  7.         public void login( String name,String pwd,int loginType ){   
  8.              if( loginType == 0 ){   
  9.                  login( name,pwd );   
  10.              } else if ( loginType == 1 ) {   
  11.                  loginByUsbKey( name,pwd );   
  12.              } else if ( loginType == 2 ) {   
  13.                  loginBySSO( name,pwd );   
  14.              }   
  15.   
  16.         }         
  17.   
  18.         public void login( String name,String pwd ){   
  19.         }   
  20.   
  21.         public void loginByUsbKey( String name,String pwd ){   
  22.         }   
  23. }  

这样做把大快的代码分成很多个小部分,每个部分因为代码不多,容易读,也会因此而变得容易修改的。类似这种情况的还有胖

        这里有一个问题需要注意:重构的密集程度问题,太多的话会影响开发进度,太少了重构难度会非常大,因此决定一个比较合适的重构周期是很重要的!

        重构代码的同时也需要对相应的说明性文档进行重构。

1.3        代码审查

从科技局项目开始,代码审查已经被提上日程,可是现在想起来,当时的做法真是有些太初级。我觉得是我的关注面错了:代码审查的过程是完成代码重构的过程!如果有些不好的代码我自己都没有看出来它需要进行重构,这个时候代码审查会议就是一个很好的剔除烂代码的过程,大家一起讨论如何对已有代码进行修改,怎么样能更好的提高代码的重用率和可读性,而不仅仅的只是关心代码中哪里少了一个空格,哪里有多了一个空格等等。

下面的代码是科技局中出现的(在一个jsp中摘抄,可以不看,举个例子而已):

java 代码
  1. String dbname = Const.DB_NAME_SB;   
  2.   String wbzh = (String) request.getSession().getAttribute("userid");    
  3.   String zcname = (String) request.getSession().getAttribute("zcname");    
  4.   String wbssht = StringUtil.getParameter(request, "wbssht""");    
  5.   String action = request.getParameter("action")   
  6.   String wbwcnx = StringUtil.getParameter(request,"wbwcnx","") ;   
  7.     if (wbssht.equals("")) {   
  8.     out.println("");   
  9.     return;   
  10.   }   
  11.   String SQL =   
  12.       " select  kjsbsqs.wbxmfl as wbjhlb , kjsbsqs.wbxmmc as wbxmmc ,  kjsbsqs.wbsbdw as wbcddw,"  
  13.       + " kjsbsqs.wbglbm as wbgkgldw, kjsbdwxx.wbdwdz as wbwddwdz, kjsbdwxx.wbfddb_xm as wbdwfrzxm , kjsbdwxx.wbfddb_dh as wbdwfzrdh,"  
  14.       + " kjsbsqs.wbxmfzr_xm as wbfzrxm , kjsbsqs.wbxmfzr_dh as wbfzrdh , kjsbsqs.wbxmlxr_xm as wblxrxm, kjsbsqs.wbxmlxr_dh as wblxrdh , kjjhxmxzb.kjkyjf as wbkyjf, "  
  15.       + " kjjhxmxzb.kjxzdw as wbkydw, kjsbsqs.wbxmbm as wbxmbh from  kjsbsqs  , kjsbdwxx , kjhtbz ,kjjhxmxzb where "  
  16.      + " kjsbsqs.wbid = kjsbdwxx.wbxm and "  
  17.       + " kjsbsqs.wbid = kjjhxmxzb.kjssxmbh and "  
  18.       + " kjsbsqs.wbid = kjhtbz.kjssxmbh and "  
  19.       + " kjhtbz.id =   " + wbssht ;   
  20.   BaseList SQL_list = new BaseList();   
  21.   SQL_list.executeStatement(SQL, dbname)   
  22.   String HTJBXX_SQL = " select wbid , wbssht from kjsbhtjbxx where wbssht = " + wbssht;   
  23.   if(SQL_list.Nums <= 0 ){   
  24.    response.sendRedirect("error.jsp");   
  25.   }     
  26.   String XMSQL = "select kjqzsj,wbxmnd from kjjhxmxzb ,kjsbsqs ,kjhtbz "  
  27.       + " where kjsbsqs.wbid = kjjhxmxzb.kjssxmbh and "  
  28.       + " kjsbsqs.wbid = kjhtbz.kjssxmbh  and  kjhtbz.id = "  
  29.       + wbssht;   
  30.   BaseList XMSQL_list = new BaseList();   
  31.   XMSQL_list.executeStatement(XMSQL, dbname);   
  32.   String ZT_SQL = " update kjhtbz set kjhtzt = 1 where kjhtzt not in (1,2,3,4) and id =  " + wbssht;   
jsp模式,处理方法是将业务逻辑从jsp中剔除出去,封装在合适的类中。
User类的login()方法将会多到100甚至1000行代码,到了那个时候,代码的维护性几乎等于0,只能祈求老天不要让它出问题。如果有一天编写代码的人不再负责该代码的维护,而要转交给你,你怎么办?写System.out.println()进行跟踪?还是采用其他方法?重构告诉我们,如果遇到大类或大方法,应该将方法分解成许多小方法,每个方法处理同一类问题:
java junit.swingui.TestRunner Test(图不知道怎么帖)
 好长时间没用,忘记了启动测试大概代码如下
   
时间:2007-05-22
又是用er的
发在一个帖子里不好么
另外整理下格式好么
这样有人会耐心看么
   
0 请登录后投票
时间:2007-05-22
ddandyy 写道
又是用er的
发在一个帖子里不好么
另外整理下格式好么
这样有人会耐心看么


什么是er?可以所有的内容都发一个帖么?第一次发没太注意
   
0 请登录后投票
时间:2007-05-22
不是 我的意思是 后两个发在回帖里 这样让别人看的时候也方便 否则如果真的想找后面的还要出去搜索么 万一有几个回帖不就乱掉了 就找不到了
ER是我打错了 应该是RE 也就是Rich Editor 是你的发帖的编辑器 如果你发代码的话 建议用BBCODE 里的CODE标签 看起来会很舒服
在JE的人都看惯那个了几乎 如果发代码的时候不加CODE的话 几乎没有人会有耐心看的

举个例子 就是这样

class Test {

        public TestSuite suite(){

                TestSuite ts = new TestSuite();

                ts.addTest( new ProcessTest() );

                return ts;

        }

}
   
0 请登录后投票
时间:2007-05-22
ddandyy 写道
不是 我的意思是 后两个发在回帖里 这样让别人看的时候也方便 否则如果真的想找后面的还要出去搜索么 万一有几个回帖不就乱掉了 就找不到了
ER是我打错了 应该是RE 也就是Rich Editor 是你的发帖的编辑器 如果你发代码的话 建议用BBCODE 里的CODE标签 看起来会很舒服
在JE的人都看惯那个了几乎 如果发代码的时候不加CODE的话 几乎没有人会有耐心看的

举个例子 就是这样

class Test {

        public TestSuite suite(){

                TestSuite ts = new TestSuite();

                ts.addTest( new ProcessTest() );

                return ts;

        }

}

查询那个已经改了,不过内容好像有点变化~~~~
   
0 请登录后投票
时间:2007-05-22
用RE的时候 发有些代码会乱掉 所以才推荐用BBCODE 肯定没有问题
   
0 请登录后投票
时间:2007-05-22
ddandyy 写道
用RE的时候 发有些代码会乱掉 所以才推荐用BBCODE 肯定没有问题

那个bbcode有没有长度限制??
   
0 请登录后投票
时间:2007-05-22
长度限制肯定有的
这个是数据库字段的长度限制
   
0 请登录后投票
时间:2007-05-22
ddandyy 写道
长度限制肯定有的
这个是数据库字段的长度限制

调整了一下,现在看着怎么样
   
0 请登录后投票
时间:2008-04-16
这种项目天生就不是以技术为导向。
能做的就是尽量把功能模块细化设计,随时可以组合,去掉
   
0 请登录后投票
论坛首页 Java版 企业应用

跳转论坛:
JavaEye推荐