Java开发规范方案.docx
- 文档编号:5537706
- 上传时间:2022-12-19
- 格式:DOCX
- 页数:22
- 大小:124.29KB
Java开发规范方案.docx
《Java开发规范方案.docx》由会员分享,可在线阅读,更多相关《Java开发规范方案.docx(22页珍藏版)》请在冰豆网上搜索。
Java开发规范方案
信息技术中心
IT应用开发技术规范
Java开发规范
编制人
架构SBU
授权人:
版本号
V1.0
生效日期:
版权说明
本文件中包含的任何文字叙述、文档格式、插图、照片、方法、过程等内容,除另有特别注明,版权均属太平洋保险所有。
未经许可任何人不得将此文件中的任何部分以任何形式进行复制,储存和传播。
版本记录
版本号
日期
修改者
说明
文件名
V0.1
2013-11-15
根据开发部的开发规范整理出初始版本
V1.0
2014-10-11
根据同一开发框架研发进展以及各部门规范的更新,重新整理定稿。
1.概述
1.1.文档目的
《中国太平洋保险股份有限公司IT应用开发技术规范》(以下简称太保IT开发规范)定义了IT应用项目开发时应遵循的技术指南,作为各项目组的开发指导性指南和代码审查的依据。
本册为Java应用开发分册,用于规范各项目在Java应用的开发。
1.2.适用范围
本指南适用于所有使用Java开发的应用项目,并且详细说明统一开发框架的相关指南,开发过程中各方必须遵循本文档定义的原则、指南及标准。
补充说明:
对于统一开发框架特有指南,将在章节中进行说明,对于这些非统一开发框架实施的项目,可不照此实施。
但建议要求相关项目应该参考,并制定自己项目的相应内容。
1.3.文档说明
本指南从技术选型、总体技术规范、展现层、业务逻辑层、数据库访问层、接口开发等方面定义了应遵循的技术规范和要求。
1.4.术语定义
1、原则:
指所有应用系统的开发框架或系统设计时必须遵守的准则或限制性条件,除非经过评审认为可以临时破例,否则是必须遵守的技术要求。
2、规范:
指应用系统开发过程中使用的某项技术应该遵循的规范。
3、指南:
指应用系统开发过程中某项技术的最佳实践,供参考和遵循。
2.技术选型规范
对于技术选型标准,要求所有Java应用项目必须以次作为选择依据。
2.1.开发工具指南
Eclipse3.7及以上版本
2.2.Java标准
项目整体采用:
JavaEE5标准;
JDK版本:
JavaSE6(JDK1.6)
2.3.源代码管理工具
源代码管理工具采用SVN,由太保统一SVNServer提供SCM服务。
2.4.依赖管理工具
采用Maven3及以上版本作为依赖管理工具,并且使用集团统一的Nexus版本库。
2.5.第三方组件选型
具体参见《CPICIT应用系统技术选型标准》
3.总体技术规范
3.1.原则
3.1.1.程序对象重用原则
原则描述:
1.应用程序中占内存大的对象要避免不断生成与复制,尤其避免在循环体中生成大对象。
2.应用系统应该尽量通过公共组件与AOP技术,减少重复性的代码。
动机说明:
✓公共组件是将通用的代码逻辑封装起来,避免重复实现,如事务控制、异常处理、日志记录等可以采用AOP技术,减少代码量,避免错误的产生。
✓由于Java的垃圾回收机制,不会立即释放不用的内存,如果短时间内大量生成大对象,容易造成内存溢出。
3.1.2.依赖解除原则
原则描述:
应用需要支持分模块独立发布,所以一定要避免包与包之间的互相依赖,如果一个包的类引用第二个包的类,那么第二个包的类不应引用第一个包的类。
动机说明:
✓如果它们互相引用,它可能意味着任何一个包都不能单独使用。
所有类最好在一个包中。
3.1.3.常量使用原则
原则描述:
应用程序中如果需要使用某常量值,必须在类中声明该值为常量,以增强程序的可读性和配置性。
对于配置型的常量建议使用枚举常量类定义。
动机说明:
✓过多的常量值的直接引用不利于程序的可读性和维护
✓枚举常量类的使用可以避免将常量值编译到业务代码中,当常量值发生变化的时候无需将所有引用常量的类都重新编译,只需编译常量类即可。
3.1.4.第三方代码使用原则
原则描述:
应用系统必须使用附录一的组件清单中的对应版本的第三方代码包,未在清单中的第三方代码的使用必须经过审核,判断它的稳定性、性能以及合法性。
动机说明:
✓第三方代码可能存在不同版本,其功能、稳定性、性能等都不相同,需要仔细研究以确定一个最符合项目要求的版本
✓部分开源代码的开源协议要求都很严格,需要避免产生不合法使用的情况
3.1.5.自动代码检查原则
原则描述:
应用程序代码必须能够通过代码检查工具(例如CheckStyle或PMD)的检查。
动机说明:
✓及时发现不符合指南的代码,避免不合格代码与程序的出现,降低开发风险。
使用说明:
通过CheckStyle或PMD等代码检查工具验证本原则。
3.1.6.自动单元测试原则
原则描述:
JAVA类中的方法必须编写单元测试代码(可以采用Junit等单元测试工具包),并进行自动化的单元测试。
动机说明:
✓在程序修改后,通过运行自动化单元测试,可以及时发现本次改动是否会影响其他代码逻辑。
而版本管理人员可以通过运行单元测试,避免代码逻辑冲突,及时发现问题,减少系统测试中出现错误的情况。
使用说明:
通过Junit和Jcoverage等单元测试工具验证单元测试的结果和覆盖度。
3.1.7.日志处理原则
原则描述:
开发人员对JAVA类进行单元测试通过之后,必须删除代码中的System.out/System.err打印语句。
这些打印语句不允许随意保留在源代码中,尤其是单元测试通过后且提交到版本管理服务器中的代码不允许出现这些语句。
应用的各类日志应该保存的指定的日志文件夹中,并根据应用名、文件大小、日期等分文件存放,便于统一管理。
错误与异常日志应能体现异常发生的时间、原因以及发生时的环境;
动机说明:
✓System.out/System.err打印占用文件句柄,在大并发量操作的时候,会对系统性能带来很大的影响。
使用说明:
系统记录日志应当使用SLF4J的org.slf4j.Logger类,应用日志必须有一定的分级日志机制,一般来说,所有输出内容都必须使用“Logger.debug();”来处理,其他的分级机制如下:
ERROR:
可导致应用不正常工作的错误以及异常;
WARN:
不会影响应用工作的错误或异常;
INFO:
应用启动与停止信息与时间以及运行过程中的重要信息等;
DEBUG:
各类调试信息。
注意:
生产环境下默认的日志级别是WARN级别,而采用统一开发框架的RunningTrackRecorder机制,INFO及以上级别的信息将可作为异常的上下文打印到日志文件中,因此对INFO级使用尤其注意,可以将一些关键信息记录下来。
3.2.规范
3.2.1.应用分层规范
应用从上到下总体分为五层,每层之间是从上到下的依赖,下层不会依赖上层。
具体每层的定位:
●展现层:
提供用户交互界面,负责接收用户的输入信息并反馈相应的系统处理结果,并提供页面交互逻辑。
●控制层(Controller):
负责完成页面与后台的衔接工作,并需要处理掉涉及到ServletAPI的所有相关工作;
1)负责完成页面数据与后台业务数据的转化(注意:
目前由于可以直接将实体类前置到页面端,因此转化工作非常有限);
2)页面数据数据基本校验,例如:
是否为空,格式是否正确等;
●接口接入层(Interface):
提供作为服务方,对外提供的接口服务,完成接口报文转换服务,并提供访问权限控制、接口异常处理等。
●服务层(Service):
负责提供系统内外的服务,承担如下几项功能:
1)事务控制——Service的所有public方法几乎均有事务,只是有些是子读事务:
2)业务流程组装,注意:
不是业务逻辑实现,一个业务流程可能仅调用一个Business的一个方法,也可能调用一个Business的多个方法,例如:
先查询、后修改,再保存,也可能出现调用多个Business的方法,具体组装是按照需求进行了;
3)由于Service可能不与Controller部署在一起,因此Service还需要对入参对象进行基本校验。
●业务逻辑层(Business):
此为可选层,如果不见此层,那么具体的业务逻辑放到Service中;如果建立此层,那么负责完成具体的业务逻辑,主要对应领域相关逻辑(Domain),相关设计可以参见DomainModel(参考DomainDrivenDesign);
●数据访问层(DataLayer):
负责数据库访问;
●系统集成层(Integration):
提供与外部系统或服务的统一集成。
3.2.2.编码字符集规范
应用系统项目开发统一采用UTF-8编码格式标准。
在eclipse环境中设置位置为下拉菜单“Window->Preferences”,选择左边树型菜单“General->Workspace”,在“Textfileencoding”中选择“Other”,再选择“UTF-8”。
3.2.3.项目工程规范
应用必须需分工程进行开发,不得将所有内容统统打包到一个工程中。
●Web应用工程,存放展现层、控制层代码,对于后台服务采用Jar引用,工程(Project)名以web结尾;
●服务工程,存放服务层、业务逻辑层、数据访问层的代码,工程名以service结尾;
●对外提供服务工程,对于系统需要对外提供服务,建议建立一个单独的对外服务工程,实现接口的相关控制逻辑,对于具体的业务逻辑还是需要引用服务工程的Jar;
●系统集成工程,对于依赖外部服务较多的项目,建议建立单独的系统集成工程,封装所有外部服务调用。
3.2.4.代码目录结构规范
3.2.4.1.Web应用目录结构规范
✓前台工程命名应该全部小写,标准为:
子系统名-web
✓前台工程的主目录结构标准如下:
说明
src
前台工程应用代码的存放目录
src/main
前台工程应用逻辑代码的存放目录
src/test
前台工程应用测试代码的存放目录
main/env
前台工程环境配置文件存放目录
main/java
前台工程应用逻辑java代码存放目录
main/resources
前台工程非环境相关配置文件存放目录
main/webapp
前台工程页面相关程序文件存放目录
✓前台工程环境配置文件存放目录标准如下:
3.2.4.2.服务工程目录结构规范
✓后台工程命名应该全部小写,标准为:
子系统名-service
✓后台工程的主目录结构标准如下:
说明
src
后台工程应用代码的存放目录
src/main/java
后台工程应用逻辑代码的存放目录
src/main/resources
后台工程环境配置文件的存放目录
src/test
后台工程应用测试代码存放目录
✓各子目录结构标准参考前台工程目录结构标准
3.2.5.对象命名规范
对象命名应该由26个大小写字母(A..Z,a..z)和_(下划线)组成,不应包含”!
@#$%”等特殊字符和数字字符,对象命名要有意义。
3.2.5.1.包(Package)命名规范
✓包名应该唯一,以com为前缀,包名的命名规范如下:
com.cpic.项目名/应用名.模块名(可以多层).分层名,
例如:
com.cpic.caf.pub.errorcode.controller
com.cpic.caf.pub.errorcode.service
✓包的命名全部为小写字母,并且只允许包含字母或数字,必须以字母开头。
3.2.5.2.类(Class)命名规范
✓所有类名都必须是名词,以大写字母开始,必须拼写出整个单词而且附加词的第一个字母必须为大写字母。
例如:
excel文件读取类的命名为ExcelFileReader
✓各层的类以各层的缩写为后缀,例如展现层的类以Action为后缀。
✓接口建议与类名一致,无需特殊处理,但如需特殊标识,建议以I作为前缀,后面紧跟的单词第一个字母大写;
✓接口实现类建议以Impl结尾;
✓对于抽象类建议以Abstract为前缀;
✓建议Entity、VO类直接取对象名称,后面带EO/VO后缀;
3.2.5.3.属性(Attribute)命名规范
✓所有实例变量都必须以小写字母开始,每个附加单词的第一个字母必须为大写。
实例变量名也应能表明该属性指所代表的类的名称。
例如theNameOfMyAttribute、invoiceLineItem、clientSearchController
✓尽量不要在成员变量名中包括类名。
例如:
不要使用Client类的clientId,只使用id
✓所有拥有一些集合(如Arraylist,Map等)的属性应为复数。
例如:
customers、parts、lineItems等
3.2.5.4.方法(Method)命名规范
✓所有方法名都必须以小写字母开始,每个附加单词的第一个字母必须为大写。
方法名也应作为方法目的的描述。
例如calculateAmount,addLineItem,connectToServer
✓不要在方法名中包括类名。
例如:
不要使用Client类的deleteClient,只使用delete
3.2.6.代码注释规范
Java提供了两种类型的注释:
程序注释和文档注释。
程序注释是由分隔符/*…*/,和//隔开的部分。
文档注释(即“doc注释”)是Java独有的。
由分隔符/**…*/隔开。
文档注释描述了Java类,接口,构造函数,方法和属性。
每个文档注释放在文档注释符/**…*/中。
所有的类和类的接口方法必须写注释,说明其完成功能、入口参数及返回值。
程序注释有四种格式:
块注释格式,单行注释,跟随注释,行尾注释。
3.2.6.1.块注释格式
块注释主要用于描述:
文件、方法、数据结构和算法。
一般在文件或者方法定义的之前使用。
也可以用在方法定义里面,如果块注释放在函数或者方法定义里,它必须与它所描述的代码具有相同的缩进形式。
块注释应该用一个空行开头,以便于代码部分区分开来。
块注释举例:
/*
*Hereisablockcomment.
*/
3.2.6.2.单行注释
比较短的注释可以放在一行中,但必须与它所跟随的代码有相同的缩进。
如果注释不可以放在一行,那么必须按照块注释的格式来写。
单行的注释会被解释为一空行。
单行注释举例:
if(condition){
/*Handlethecondition.*/
...
}
3.2.6.3.跟随注释
非常短的注释可以和它所描述的代码放在同一行。
但要保证代码和注释之间有足够的间隔一般应该大于5个字符应以可阅读性高、美观为标准进行适当调整,在同一块代码中不止一个这样的注释时它们应该对齐。
跟随注释举例:
if(a==2){
returnTRUE;/*specialcase*/
}else{
returnisPrime(a);/*worksonlyforodda*/
}
3.2.6.4.行尾注释
注释标记“//”能够注释一行或者该行由“//”开始直到行尾的部分。
行尾注释不能用在多行文本注释中。
但它可以将多行代码注释掉。
这三种注释方法举例如下。
if(foo>1){
//Doadouble-flip.
...
}
else{
returnfalse;//Explainwhyhere.
}
//if(bar>1){
//
////Doatriple-flip.
//...
//}
//else{
//returnfalse;
//}
3.3.指南
3.3.1.java代码指南
3.3.1.1.变量声明
1)每行定义变量数目
每行定义的变量数目必须有且只有一个。
例如:
intlevel;//indentationlevel
intsize;//sizeoftable
如果final类型的成员被分配了编译时的常量,可以将它定义成static。
尽可能不使用非终态公共静态变量,因为没有机制来检测改变此变量的代码是否有适当的权限,非终态公共静态变量允许在两个保护域间建立隐蔽通道。
如,Non-finalstaticString字段可能会把序列化好的java对象传给没有权限访问它们的其他保护域。
如:
protectedstaticStringsecularRisk="";
避免在操作符中赋值。
如:
while((count=input.read(buffer))!
=-1)
2)变量初始化
在声明局部变量的时候就要初始化变量。
私有成员可以定义成final,只能在声明或者构造函数中进行初始化。
避免重新给参数分配值,完全可以使用临时的局部变量来替代。
3)变量定义位置
在for循环里的循环变量可以在for语句里面定义。
for(inti=0;i 注意: 应避免局部变量屏蔽了外层变量的作用范围。 也就是说不要在内部块中声明一个与外部块某个变量同名的变量。 例如类似下面的情况应避免: intcount; ... myMethod(){ if(condition){ intcount;//与外部的count变量重名,应该避免! ... } ... } 避免保留未使用的局部变量。 4)Boolean、String 程序中不允许对Boolean、String进行实例化 建议可以使用Boolean.TRUE或者Boolean.valueOf(true)来代替Boolean的实例化 5)字符串变量转换 当转换原始对象成字符串类型时,避免创建不必要的临时对象。 如: //该方法将浪费一个对象 Stringfoo=newInteger(x).toString(); //更好的应该使用如下方法 returnInteger.toString(x); 6)Vector、ArrayList 建议使用ArrayList来代替Vector,可以获得更好的性能。 Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快。 7)Null 避免指配NULL值给变量,当一个变量被赋为NULL值时,会暗示垃圾收集器对它进行回收。 类和接口声明 类和接口的声明应该遵循以下指南: 1)在方法名和参数列表的圆括号以及括号后的第一个参数间都没有空格。 2)开括号“{”必须与声明语句放在同一行。 3)闭括号“}”必须与声明语句有相同的缩进格式。 4)如果类或者接口实现内容为空,则可以将“}”放在“{”后面。 5)不要在构造函数内调用可重写的方法。 6)在final类中避免出现protected字段。 7)抽象类应该包含抽象方法。 8)方法之间要用一个空行隔开。 9)在interface中,变量成员自动修饰为publicstaticfinal,方法自动修饰为abstract;类或者接口嵌套在interface中自动修饰为public和static。 10)序列化的类建议提供一个SerialVersionUID。 serialVersionUID作用: 序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。 11)继承有两种: 实现(implementation)与接口(interface)。 尽量使用接口或者抽象类降低耦合性,即应当使用java接口和抽象类进行变量类型的声明、参数类型的声明、返回类型的声明、数据类型的转换等。 要保证这一点: 一个具体类应当只实现接口和抽象类中声明的方法,而不应当给出多余的方法。 3.3.1.2.eauals方法使用指南 不要使用equals()来比较NULL值,因为如果xxx是null的话xxx.equals(null)会抛出NullPointerException。 equals()比较二者内容是否相等,比较二者是否为同一引用,即指向二者的指针是否相等,equals()是类的方法,调用它必然要引用对象,如果xxx的值为null,必然会抛异常;如果xxx的值不为null,此方法返回false,也就是说不可能返回true。 3.3.1.3.方法编码指南 1)方法代码行不要超过100行,方法太长,首先问题是代码复杂度较高;其次代码阅读较为困难。 结果过长的方法是代码重构,通过抽取方法,提到方法的内聚性。 2)避免出现过于复杂逻辑的方法 方法的复杂度是由方法内加入的判定点(DecisionPoint)的数量决定的,包括如if、while、for、switch…case的case语句等,例如: 1-4(低复杂度) 5-7(中等复杂度) 8-10(高复杂度) 10+(超高复杂度) 3)避免出现内容过多的方法 指南整洁的方法有利于阅读者更好的理解方法的功能,因为程序员在开发过程中要避免过多的内容出现在一个方法中。 一般来讲一个方法在30行代码之内为佳。 如果方法的代码量超过30行应该考虑对方法重构。 4)避免一个方法承载、传递过多的参数 在实际开发过程中,复杂的业务逻辑可能会使程序员在方法的调用的过程中传递了过多的参数 如: publicvoiddelete( StringstatisDate,StringclassCode, StringriskCode,StringcomCode, Stringhandler1Code,StringagentCode, StringuseNatureCode,StringbusinessNature, Stringmotorcadeflag,StringcarKindCode, StringuseYears,StringinsuredNature, StringkindCode) throwsException{……. 遇到这样的情况要尽量将变量进行整合为对象,方法的参数一般以不超过5个为佳。 5)没有必要的final修饰。 当一个类是final类时,它的所有方法也是自动修饰为final。 如 publicfinalclassDDAFinalDataTool{ ……. publicfinalstaticStringgetClauseType (StringuseNatureCode){ …… } } 6)重写equals()时,建议同时重写hashCode();或重写hashCode()时同时重写equals()。 java.lnag.Object中对hashCode的约定: ●在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,则对该对象调用hashCode方法多次,它必须始终如一地返回同一个整数。 ●如果两个对象根据equals(Objecto)方法是相等的,则调用这两个对象中任一对象的hashCode方法必须产生相同的整数结果。 ●如果两个对象根据equals(Objecto)方法是不相等的,则调用这两个对象中任一个对象的hash
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 开发 规范 方案