怎样编写高质量的Java代码

标签: 质量 java 代码 | 发表时间:2014-03-12 16:53 | 作者:
出处:http://www.iteye.com
本文来自 LEE的博客,他首先向大家讲述怎样辨别一个项目代码的好坏、如何区分优秀代码和腐化代码,最后给大家讲述如何写出高质量的Java代码。

代码质量概述



怎样辨别一个项目代码写得好还是坏?优秀的代码和腐化的代码区别在哪里?怎么让自己写的代码既漂亮又有生命力?接下来将对代码质量的问题进行一些粗略的介绍。也请有代码质量管理经验的朋友提出宝贵的意见。

代码质量所涉及的5个方面:编码标准、代码重复、代码覆盖率、依赖项分析、复杂度分析。这5个方面很大程序上决定了一份代码的质量高低。我们分别来看一下这5方面:

  • 编码标准:这个想必都很清楚,每个公司几乎都有一份编码规范,类命名、包命名、代码风格之类的东西都属于其中。
  • 代码重复:顾名思义就是重复的代码,如果你的代码中有大量的重复代码,你就要考虑是否将重复的代码提取出来,封装成一个公共的方法或者组件。
  • 代码覆盖率:测试代码能运行到的代码比率,你的代码经过了单元测试了吗?是不是每个方法都进行了测试,代码覆盖率是多少?这关系到你的代码的功能性和稳定性。
  • 依赖项分析:你的代码依赖关系怎么样?耦合关系怎么样?是否有循环依赖?是否符合高内聚低耦合的原则?通过依赖项分析可以辨别一二。
  • 复杂度分析:以前有人写的程序嵌套了10层 if else你信吗?圈复杂度之高,让人难以阅读。通过复杂度分析可以揪出这些代码,要相信越优秀的代码,越容易读懂。
上面解释了代码质量相关的5个方面,在实际开发环境中,已经有很多工具为我们解决以上5个方面的问题,下列5个eclipse插件分别对这5个问题有很好的支持:

注:某些插件需要科学上网才能更新

1. 编码标准(CheckStyle的使用)

在Eclipse上安装好了CheckStyle插件后,我们来建一个类用它跑一下。这个类很简单,一个常见的用户实体,包含了ID,用户名、密码、邮件等属性,并包含get set方法,一个标准的POJO。运行CheckStyle检查一下:



一个我们平时再普通不过的一个类,被CheckStyle弄出这么多问题,情何以堪,我们来看看究竟是什么情况?

看一下这些警告信息:

line 1、 ,说缺少package-info.java文件。

line 2、 ,说第一句注释要以“.”结尾。

line 30、 ,缺少java doc注释。

line 35、 ,getId不是继承的方法,必须指定abstract,final或空。另外也缺少java doc注释。

这个类基本就这四类毛病,缺少package-info.java文件,这个文件是做什么的呢?他是用来描述包注释的类,有一定的特殊性,要想详细了解请百度。如果对你的项目没有太大的影响,可以忽略它。配置CheckStyle的方法我们等会再说。第一句注释要以“.”结尾,这看你的习惯,你确定需要这个,你就保留,不需要就忽略。缺少Java doc,对于Java类的属性来说,注释是必要的,所以这个要保留。不是继承的方法,需要加上final关键字,如果你有这个习惯,就保留,反之忽略。

我们这里只是建立了一个最简单的类用CheckStyle来检查,随着你的类代码越来越多,逻辑越来越复杂,CheckStyle能检查出来的毛病也越来越多。
常见的CheckStyle错误有这些:
引用
1.Type is missing a javadoc commentClass  
缺少类型说明
2.“{” should be on the previous line
“{” 应该位于前一行
3.Methods is missing a javadoc comment
方法前面缺少javadoc注释
4.Expected @throws tag for “Exception”
在注释中希望有@throws的说明
5.“.” Is preceeded with whitespace “.”
前面不能有空格
6.“.” Is followed by whitespace“.”
后面不能有空格
7.“=” is not preceeded with whitespace
“=” 前面缺少空格
8.“=” is not followed with whitespace  
“=” 后面缺少空格
9.“}” should be on the same line   
“}” 应该与下条语句位于同一行
10.Unused @param tag for “unused”
没有参数“unused”,不需注释
11.Variable “CA” missing javadoc
变量“CA”缺少javadoc注释
12.Line longer than 80characters  
行长度超过80
13.Line contains a tab character
行含有”tab” 字符
14.Redundant “Public” modifier
冗余的“public” modifier
15.Final modifier out of order with the JSL
suggestionFinal modifier的顺序错误
16.Avoid using the “.*” form of import
Import格式避免使用“.*”
17.Redundant import from the same package
从同一个包中Import内容
18.Unused import-java.util.list
Import进来的java.util.list没有被使用
19.Duplicate import to line 13
重复Import同一个内容
20.Import from illegal package
从非法包中 Import内容
21.“while” construct must use “{}”
“while” 语句缺少“{}”
22.Variable “sTest1” must be private and have accessor method
变量“sTest1”应该是private的,并且有调用它的方法
23.Variable “ABC” must match pattern “^[a-z][a-zA-Z0-9]*$”     
变量“ABC”不符合命名规则“^[a-z][a-zA-Z0-9]*$”
24.“(” is followed by whitespace   
“(” 后面不能有空格
25.“)” is proceeded by whitespace
“)” 前面不能有空格

可以看出CheckStyle检查出来的问题,大多是编码规则以及风格上的问题,这是编写高质量代码最基本的。值得注意的是,我们将一些优秀的开源代码用CheckStyle来检查也会检查出不少问题,这不能不说这些开源不优秀,而是每个公司组织有自己的编写规范度,这个度既可以减少程序员的工作量又可以让代码的可读性合格,但这个度不一样符合CheckStyle的完整标准。所以我们一般使用CheckStyle都不会用他的默认标准,而是通过配置,制定适合自己的编码规则。

自定义CheckStyle规则:



打开CheckStyle配置,新建一个配置,选择外部配置文件。在这之前最好导出一个Eclipse自带的CheckStyle配置文件(sun_checks.xml),然后重命名作为一个外部的配置导进去,这么做的目的是导入之后可以修改相应的配置,达到自定义配置的目的(因为Eclipse自带的配置是加锁的,不能修改)。导入之后,点击右边的“Configure”进行编辑。

先去掉缺少package-info.java文件的提示:



再将第一句注释要以“.”结尾这个规则去掉,双击“Style javadoc”,将窗口内“checkFirstSentence”勾选去掉。



对于实体类,属性有了注释,get set方法也不需要注释了,双击“Method javadoc”将allowMissingPropertyJavadoc勾选中。



“getId不是继承的方法,必须指定abstract,final或空”,如果你懒得在方法上加“final”,这条规则也可以去掉。

如果你不想每一个参数都加“final”,还需要把参数的final规则去掉:



另外还有一个错误“'id' hides a field.”,原因是方法的参数和类里面定义的域重名了,但使用eclipse生成的get set方法都会这样,所以可以忽略此项。



至此我们再使用checkstyle检查一篇,发现仅剩下属性缺少注释这个警告。



对每个属性加上java doc注释,所有问题都清除了。以此类推,解决checkstyle问题的方法就是:1、按规则解决代码问题;2、如果觉得这个问题对你的项目质量影响不大,则可以忽略它。

2. 代码重复(PMD的CPD的使用)

对于多人开发的项目,难以避免出现重复代码的问题,尽管我们尽量对共用的代码进行了封装,但随着需求的增加、人员技术水平差异、沟通不足等原因,重复代码会越来越多。这不仅严重影响代码质量,也无形中增加了代码量。
注:精简的程序和高复用度的代码是我们一直追求的目标。
PMD的CPD工具就是为检查重复代码而生的。右键项目--->PMD---->Find Suspect Cut and Paste,执行重复代码检查:



检查出来的重复代码,可以双击查看。然后根据业务逻辑以及代码特征,决定要不要做封装、怎么封装。

3. 代码覆盖率(Eclemma的使用)

一份质量合格的代码,不仅包含功能程序本身也包含了对应的测试代码,Eclemma插件可以用来统计测试代码覆盖整体代码中的比率,以此来评估代码的功能性和稳定性。

使用Junit编写好测试用例之后,右键Coverage As--->Junit Test,运行测试用例,Eclemma会统计出相关的代码覆盖率:



根据这个结果,你可以看出自己编写的测试用例覆盖到了那些代码,而没有覆盖到的代码,则有可能成为代码质量的盲区。

4. 依赖项分析(JDepend的使用)

随着程序业务逻辑的增加,代码的依赖关系也变的越来越复杂,JDepend插件可以统计包和类的依赖关系,分析出程序的稳定性、抽象性和是否存在循环依赖的问题。右键包--->Run JDepend Analysis:



看一下这几项指标:

  • CC(Number of Classes):被分析package的具体和抽象类(和接口)的数量,用于衡量package的可扩展性。如果一个类中实现了其他类,如实现了监听类,则监听类的数目也记录在此。
  • AC(Abstract classes):抽象类和接口的数量。
  • Ca(Afferent Couplings):依赖于被分析package的其他package的数量,用于衡量pacakge的职责。即有多少包调用了它。
  • Ce(Efferent Couplings):被分析package的类所依赖的其他package的数量,用于衡量package的独立性。即它调用了多少其他包。
  • A(Abstractness):被分析package中的抽象类和接口与所在package所有类数量的比例,取值范围为0-1。
  • I(Instability):I=Ce/(Ce+Ca),用于衡量package的不稳定性,取值范围为0-1。I=0表示最稳定,I=1表示最不稳定。即如果这个类不调用任何其他包,则它是最稳定的。
  • D(Distance):被分析package和理想曲线A+I=1的垂直距离,用于衡量package在稳定性和抽象性之间的平衡。理想的package要么完全是抽象类和稳定(x=0,y=1),要么完全是具体类和不稳定(x=1,y=0)。取值范围为0-1,D=0表示完全符合理想标准,D=1表示package最大程度地偏离了理想标准。即你的包要么全是接口,不调用任何其他包(完全是抽象类和稳定),要么是具体类,不被任何其他包调用。
  • Cycle:循环依赖的数量。
有个这个报告我们就可以有针对性的对代码进行设计和重构。

5. 复杂度分析(Metrics的使用)

对于阅读代码的人来说,越简单的代码越好理解和维护,如果你的代码阅读起来很费劲或者你自己过段时间后再来看都看不懂,你就得想办法解决下代码的复杂度问题了。Metrics插件可以帮你做到这点。
首先在Java透视图下右键一个项目---->Properties,选择Metrics,勾选Enble Metrics。



然后Window--->Show View---->Other---->Metrics View



打开Metrics视图,点击右上角运行图标,即可得到复杂度分析的结果:



可以根据复杂度指标,对自己的程序进行优化。

小结

本文介绍了和java代码质量相关的5个方面问题,并介绍对应eclipse插件的用法和作用。在我们实际开发中,尽量根据自己公司和团队的情况来制定一些检查规则,来提高代码质量。并且在大多数情况下,会有两个检查环节,即本地检查和持续集成环境的检查,我们常用的Hudson就可以集成很多插件。

本文转载自: LEE的博客

感谢 学良3 投递这篇资讯

资讯来源: LEE的博客

已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [质量 java 代码] 推荐:

编写高质量的Java代码

- - 研发管理 - ITeye博客
Java 开发通用方法和准则. 不要在变量和常量出现易混淆字母:int i=1l;. 三元操作符的值类型务必保持一致;. 避免带有变长参数的方法重载:Java 5 引入了变长参数,varags, 用…表示,变长参数必须是最后一个参数,一个方法不能有多个变长参数;. 别让null和空值影响到变长方法,主要出现在在变长方法的重载;.

怎样编写高质量的Java代码

- - ITeye资讯频道
本文来自 LEE的博客,他首先向大家讲述怎样辨别一个项目代码的好坏、如何区分优秀代码和腐化代码,最后给大家讲述如何写出高质量的Java代码. 怎样辨别一个项目代码写得好还是坏. 优秀的代码和腐化的代码区别在哪里. 怎么让自己写的代码既漂亮又有生命力. 接下来将对代码质量的问题进行一些粗略的介绍. 也请有代码质量管理经验的朋友提出宝贵的意见.

怎样编写高质量的java代码

- - Web前端 - ITeye博客
怎样辨别一个项目代码写得好还是坏. 优秀的代码和腐化的代码区别在哪里. 怎么让自己写的代码既漂亮又有生命力. 接下来将对代码质量的问题进行一些粗略的介绍. 也请有过代码质量相关经验的朋友提出宝贵的意见. 代码质量所涉及的5个方面,编码标准、代码重复、代码覆盖率、依赖项分析、复杂度分析. 这5方面很大程序上决定了一份代码的质量高低.

提高你的Java代码质量吧:不要让类型默默转换

- - CSDN博客推荐文章
在Java运算中的类型转换,是先运算在进行类型转换的. System.out.println("月亮照射到地球需要1秒,计算月亮到地球的距离. System.out.println("月亮与地球的距离是:" + dis1 + "米");. System.out.println("太阳照射到地球上需要8分钟,计算太阳到地球的距离.

提高你的Java代码质量吧:警惕数组的浅拷贝

- - CSDN博客编程语言推荐文章
在日常工作中,我们会遇见很多数组的拷贝和复制的问题,但是在你使用系统提供的API进行编码的时候,无形中会留下浅拷贝的隐患. 有这样一个例子,第一个箱子里面与赤橙黄绿青蓝紫7色气球,现在希望第二个箱子也放入7个气球,其中最后一个气球改为蓝色,也就是赤橙黄绿青蓝蓝七个气球. //第二个箱子的小球是拷贝的第一个箱子里的.

Java代码优化

- - ImportNew
2016年3月修改,结合自己的工作和平时学习的体验重新谈一下为什么要进行代码优化. 在修改之前,我的说法是这样的:. 就像鲸鱼吃虾米一样,也许吃一个两个虾米对于鲸鱼来说作用不大,但是吃的虾米多了,鲸鱼自然饱了. 代码优化一样,也许一个两个的优化,对于提升代码的运行效率意义不大,但是只要处处都能注意代码优化,总体来说对于提升代码的运行效率就很有用了.

java代码开发规范

- - BlogJava_首页
格式规范:                                                                      .       1、TAB空格的数量. 编辑器上的TAB空格数量统一取值为4.       2、换行, 每行120字符.       3、if语句的嵌套层数3层以内   .

Java 代码性能优化

- - IT瘾-geek
代码 优化,一个很重要的课题. 可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢. 这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗. 没用,但是,吃的小虾米一多之后,鲸鱼就被喂饱了. 代码优化也是一样,如果项目着眼于尽快无BUG上线,那么此时可以抓大放小,代码的细节可以不精打细磨;但是如果有足够的时间开发、维护代码,这时候就必须考虑每个可以优化的细节了,一个一个细小的优化点累积起来,对于代码的运行效率绝对是有提升的.

2011年度最牛逼java代码

- sunseesiu - ITeye论坛最新讨论
作者: 5172306 . 声明: 本文系ITeye网站发布的原创文章,未经作者书面许可,严禁任何网站转载本文,否则必将追究法律责任. 已有 16 人发表回复,猛击->>这里<<-参与讨论. —软件人才免语言低担保 赴美带薪读研.

Java代码编写的30条建议

- - inJava
(1) 类名首字母应该大写. 字段、方法以及对象(句柄)的首字母应小写. 对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字母. 若在定义中出现了常数初始化字符,则大写static final基本类型标识符中的所有字母. 这样便可标志出它们属于编译期的常数. Java包(Package)属于一种特殊情况:它们全都是小写字母,即便中间的单词亦是如此.