1、Java项目组开发规范33页概述一.1 编写目的为规范FSOP项目的开发实施工作,特制定本规范。为了提高软件开发质量,降低开发周期,增强代码的可重用性和易读性,使软件便于维护,开发人员间便于交流和协作,特总结出开发规范,以为参考。一.2 面向读者从事FSOP项目的开发、实施工作的相关人员。一.3 名词解释本节对手册中涉及到的术语进行简单描述。程序结构一.4 包结构项目中的所有代码,必须符合如下的结构:1、各子系统的模块:com.icss.fsop.subsys.module.servlet.xxServletcom.icss.fsop.subsysmon.util.xxUtilcom.icss
2、.fsop.subsysmon.hander.xxHandercom.icss.fsop.subsysmon.sql.xxSqlcom.icss.fsop.subsysmon.entity.xxxx其中subsys是子系统的名称,module是模块的名称,xxServlet和xxHandler是模块下面的Servlet和Handler,允许有多个Servlet和Handler同时存在,建议同一个模块下,用多套Servlet和Handler处理不同的业务对象;util存放该模块专用的类;package/class可以任意级别的包或者类;2、子系统之外的模块:com.icss.fsop.sm.mo
3、dule.servlet.xxServletcom.icss.fsop. smmon.util.xxUtilcom.icss.fsop. smmon.hander.xxHandercom.icss.fsop. smmon.sql.xxSqlcom.icss.fsop. smmon.entity.xxxx其中sm是system manage的简写,其他同上;3、公共的类:com.icss.fsopmon.package/class含义同上。一.5 相关类1、对于Servlet,必须继承ServletBase,必须在Servlet中处理与request和response相关的操作,一般是取参数和设
4、置属性等操作;2、对于Handler,必须继承HandlerBase,该类的方法中,不能用request和response作为参数,更不能用Servlet作为参数;3、程序中使用到的SQL,一律在XXXSQLBuilder中进行拼写,该类属于util包,需要继承SQLBuilderBase,其构造函数为私有类型,并且要实现静态方法getSQLBuilder(conn),根据不用的数据库类型,返回不同的实例。JAVA规范一.6 核心原则1 软件工程化2 面向对象3 能简单不复杂4 强调团队协作一.7 命名规范程序内的所有标识符(包括包名、类名、接口名、方法名、变量名)都应由字母、数字和下划线组成
5、,并以字母开头;统一采用英文命名,用词应当准确,禁止使用中英文混合的方式命名,如果可能的话,尽量使用有意义的英文单词或多个单词的缩写命名(缩写应该是被广泛使用的缩写),做到见名知意;标识符的长度应当符合“min-length & max-information”原则;程序中不要出现仅靠大小写区分的相似的标识符;在使用英文字母起标识作用时要注意,尽量不使用 “O”,“Z”,“I”等单个字符,以避免与数字“0”,“2”,“1”混淆。一.7.1 包、类和接口1、所有包名全部小写,只能使用英文字母,不得使用数字和其他符号;2、类名使用有意义的英文单词或单词的组合,每个单词的首字母大写,如果是实现接口的
6、类,可酌情使用Imp结尾,英文单词一般为名词。3、接口名使用有意义的名词和形容词的组合,每个单词的首字母大写,名称前不需要添加前缀“I”,英文字母i的大写。一.7.2 方法方法命名使用动词或“动词+名词”的组合,名称的首字母小写,名称中其他词的首字母大写。对于取值的方法(getter method),加“get”作前缀;对于设置的方法(setter method),加“set”作前缀;对于布尔型的方法(boolean method),加“is”作前缀;用正确的反义词组命名具有互斥意义或相反动作的函数,例如getValue(),setValue()。 一.7.3 变量变量命名使用名词或名词 “形
7、容词名词”的组合,名称的首字母小写,名称中其他词的首字母大写。尽量避免单个字符的变量名,除非是一次性的临时变量。临时变量通常被取名为i,j,k,m 和n,它们一般用于整型;c,d,e,它们一般用于字符型。用正确的反义词组命名具有互斥意义的变量,例如: int minValue和int maxValue。尽量避免名字中出现数字编号,如Value1,Value2等,除非逻辑上的确需要编号。命名应尽量使用匈牙利命名法,成员变量用长名字,参数和局部变量用短名字,一般由小写字母开头的单词组合而成。类成员变量前一般应加上m_,静态变量应加上s_,紧接着是变量的类型(只限于JDK内置类型)。临时变量应参照如
8、下类似的格式书写,如ltmp ,tmpStr,tempStr等。例如:m_nTotalNum,m_strPath,s_bRcving类型前缀整型n,i长整型l无符号整型u字符ch布尔量b浮点数f双精度浮点d字符串str,sz一.7.4 常量常量(static final 变量)名字的每个字母都大写,并且指出完整含义,词与词之间用下划线分隔。一.8 代码结构代码组织要清晰,严格控制函数的长度和每行代码的长度,,(,),if,else,do,while,for,case等要对应整齐,缩进全部用Tab键(4个空格)。变量的定义要集中,函数间要有空行分开,一个程序中的空行数目最好占8%-16%。多态函
9、数和功能相近的函数集中放在一起。代码应该简洁、清楚并讲述了所发生的一切,我们的目标应该是写出最清晰的代码,而不是最巧妙的代码。有些不易理解的变量或函数应作注释,难懂的代码要有注解,在文件的开始处有该文件的用途描述。一定要保持注释的一致性。代码的重用要仔细,删掉从来没有用过的函数或变量,大篇幅注释掉的代码行也应删除,以免使程序混乱难读。工程中不起作用的文件或类应删除,工程目录下的非工程文件也应该移走,保持工程的清洁,避免混淆难于管理。一.8.1 缩进代码缩进是指通过在每行代码前键入空格或制表符的方式,表示每行代码之间的层次关系。任何编程语言都需要代码缩进规范程序的结构,采用代码缩进的编程风格有利
10、于代码的阅读和理解。在本项目的开发中,统一采用TAB(4个空格)进行代码缩进。在遇到有关类、结构、函数或过程、以及枚举等等复杂程序结构的定义的时候,我们通常需要将它的内容缩进一层。在 C/C+/C#/Java 语言中,大括号是一个非常明显的标志,凡是遇到大括号,都应该直接联想到缩进。一.8.2 行宽当一条语句太长而超出一定的宽度时,应该折行书写,尽量避免一行的长度超过80 个字符。一.8.3 换行需要折行时,从第二行起到该语句结束之间的各行应该缩进一层,至下一条语句时再恢复原来的缩进位置。这一点我相信大家都能理解并愿意遵循,然而问题的焦点并不在于要不要换行,而在于在什么位置换行。当一个表达式不
11、能在一行内写完,参照下面的标准换行:逗号后换行,操作符后换行,换行时保证代码意义的连贯性。在换行时,我们通常在一个变量或者常量之前换行,把逗号之类的分隔符、运算符留在前一行的行尾。函数调用时,如果参数个数很多,或者要传递的表达式写起来很长,那么也会涉及到长语句换行问题;在一些必要的情况下,我们为了清晰地列出函数的每一个参数,可以每行只书写一个参数,原则是:尽可能地在参数与参数之间换行,并将逗号保留在上一行行末。下面是经常使用的一些换行的示例代码:代码示例1:由于代码过长而进行断行bitmap = new Bitmap(size.Width, size.Height, System.Drawin
12、g.Imaging.PixelFormat.Format32bppArgb);代码示例2:对于一个超长表达式,我们可以在某两个表达式项之间断开:if (f = ImageFormat.Jpeg.Guid | f = ImageFormat.Tiff.Guid | f = ImageFormat.Png.Guid | f = ImageFormat.Exif.Guid) supportsPropertyItems = true;else supportsPropertyItems = false;原本一个很长的条件表达式,通过在“|”运算符处换行,显得更加地清晰。有一点需要我们注意的是,当我们进
13、行折行时,要将折行位置处的分隔符(如前一例中的逗号,这一例中的“|”运算符等)留在上一行的行末,给人以“此行并未结束”的直观印象。代码示例13:寻找最佳的断行位置double containerAspectRatio = (double)container.ClientWidth / container.ClientHeight;如此一来,这个除法算术表达式就显得较为完整,相比前一种写法而言更能体现其内在的逻辑关系。通常我们会选择整个表达式中最高的关系层次进行断行,例如上述代码中的“赋值号”和“除号”都是可以考虑的断行点,但相比较而言,除号连接的这个算术表达式只是整个赋值表达式的右半部分,如果
14、在除号处断行,那么不但整个表达式会被截断,连局部的这个除法表达式也会被截断;反之,我们选择在赋值号处换行,可以保持除法表达式的完整,最大限度地减少换行对语句整体结构的破坏,能够更加清楚地表达出原来的逻辑。代码示例14:将函数调用中的每一个参数都分行书写Rectangle imageBounds = new Rectangle( itemBounds.X + padding, itemBounds.Y + padding, itemBounds.Width - padding * 2, itemBounds.Height - padding * 2当参数数量较多,参数较长或者包含表达式的时候,这
15、种排版比起单独写成一行更为直观醒目。一.8.4 长度每个函数主要逻辑语句的长度以30个自然行以下为宜,建议不要超过50行,如果超过80行就应该重新组织。如果单独成行,则其所在的行不在计算的范围内,catch/finally语句块中的语句不计算在内。一.8.5 括号在大括号语法中,缩进时大括号的写法有不同的几种,个人认为,前面所用的那种左右括号单独一行的写法最为清晰,因为可以最好地反映出括号的配对情况。具体使用何种方式并不重要,重要的是,要保持方式风格的统一,不能在同一个项目中出现不同的风格。风格1看起来紧凑些,可以减少代码的行数,但是在其他代码存在换行的情况下,不容易发现配对的括号,必须要借助
16、IDE提供的功能才可以,建议使用风格2,这样的代码看起来更清晰一些,这点比较重要;/风格1if ( condition) doSomethingIf(); else doSomethingElse();/风格2if ( condition) doSomethingIf(); else doSomethingElse();一.8.6 注释注释是用来解释程序做什么(What),为什么这样做(Why),以及要特别注意的地方的,而不是注释程序是怎么工作的(How),你的程序本身就应该能说明这一问题,如果程序的逻辑过于复杂,添加一些注释也是有必要的。例如:下面的注释是必须的:/go thru the a
17、rray, note the last element is at len-1for (i = 0; ilen; i+) DoSomeThing();下面的注释是多余的/this loop starts the i from 0 to len, in each step, it/ does SomeThingfor (i = 0; ilen; i+) DoSomeThing();Java 程序有两类注释:实现注释(implementation comments)和文档注释(documentcomments)。实现注释使用/*.*/和/界定的注释。文档注释是Java 独有的,并由/*.*/界定。
18、切记,注释要随着程序的修改而不断更新,一个误导的(Misleading)注释往往比没有注释更糟糕。另外,注释(包括所有源代码)建议只用ASCII字符,不要用中文或其他特殊字符,它们会极大地影响程序的可移植性。一.8.6.1 单行注释短注释可以显示在一行内,并与其后的代码具有一样的缩进层级。如果一个注释不能在一行内写完,就该采用多行注释(参见多行注释)。单行注释之前应该有一个空行。例如:if (condition) /* Handle the condition. */.或者if (condition) /Handle the condition. .一.8.6.2 多行注释多行注释通常用于提供
19、对方法,数据结构和算法的描述。多行注释常被置于每个类和方法开始处,或者用于需要对某一实现细节做详细说明时。例如:/* Here is a block comment.*/一.8.6.3 行末注释极短的注释与它们所要描述的代码位于同一行,注释界定符是/或者/* */,可以注释掉整行或者一行中的一部分。例如:if (a = 2)return true; / special caseelsereturn false; /* special case */一.8.6.4 文档注释文档注释描述Java 的类、接口、构造器,方法,以及字段(field)。每个文档注释都会被置于注释定界符/*.*/之中,一个
20、注释对应一个类、接口或成员。该注释应位于声明之前,文档注释的第一行(/*)不需缩进,随后的文档注释每行都缩进1 格(使星号纵向对齐)。例如:/* The Example class provides .*/public class Example /* the field description .*/ private int iCount = 0;/* the method description .* param * return * throws*/ public void doSomething() 若你想给出有关类、接口、变量或方法的信息,而这些信息又不适合写在文档中,则可使用实现块
21、注释或紧跟在声明后面的单行注释。例如,有关一个类实现的细节,应放入紧跟在类声明后面的实现块注释中,而不是放在文档注释中。文档注释不能放在一个语句块内使用。一.8.7 声明变量的声明:推荐一行声明一个变量,因为这样以利于写注释;尽量在声明变量的同时进行初始化,唯一不这么做的理由是变量的初始值依赖于某些先前发生的计算;避免声明的局部变量覆盖上一级声明的变量。例如,不要在内部代码块中声明相同的变量名;只在代码块的开始处声明变量,不要在首次用到该变量时才声明。定义类的成员变量时,总的定义顺序是先定义静态变量后定义实例变量,在每种类型的变量中,变量顺序依次为:公共(public)变量,受保护(prote
22、cted)变量,私有(private)变量。一.8.8 语句if、for、do、while、case、switch、default等语句自占一行,且if、for、do、while等语句的执行语句部分无论多少都要加括号。尽量减少嵌套语句的层数,最好不好超过4层,如果多于4层,则应该对函数进行重构。一.8.8.1 if-else只有if的语句:if ( condition ) /do something 含有else的语句:if ( condition ) /do something else /do something含有else-if的语句:if ( condition ) /do somet
23、hing else if( condition2 ) /do something一.8.8.2 for语句一个for 语句应该具有如下格式:for (initialization; condition; update)statements;一个空的for 语句(所有工作都在初始化,条件判断,更新子句中完成)应该具有如下格式:for (initialization; condition; update) 当在for 语句的初始化或更新子句中使用逗号时,避免因使用三个以上变量,而导致复杂度提高。若需要,可以在for 循环之前(为初始化子句)或for 循环末尾(为更新子句)使用单独的语句。一.8.8
24、.3 while语句一个while 语句应该具有如下格式while (condition)statements;一个空的while 语句应该具有如下格式:while (condition) 一.8.8.4 do-while语句一个do-while 语句应该具有如下格式:do statements; while (condition);一.8.8.5 switch语句对于有多个分支的代码,每个分支一行,且必须包含默认(default)分支。一个switch 语句应该具有如下格式:switch (condition) case ABC:statements;break;case XYZ:state
25、ments;break;default: statements;break;一.8.8.6 try语句一个try-catch 语句应该具有如下格式:trystatements;catch (ExceptionClass e) statements;finally statements;其中finally 语句块是可选的。一.8.8.7 空语句空行将逻辑相关的代码段分隔开,以提高可读性。下列情况应该总是使用两个空行: 1、多个类(接口)声明之间下列情况应该总是使用一个空行:1、两个方法之间2、语句块内的局部变量和方法的第一条语句之间3、注释之前4、一个方法内的两个逻辑段之间一.8.8.8 空格下
26、列情况应该使用空格:1、一个紧跟着括号的关键字应该被空格分开,例如:while (true)2、空白应该位于参数列表中逗号的后面;obj.doSomething(arg1, arg2, arg3);3、所有的二元运算符,除了.,应该使用空格将之与操作数分开。一元操作符和操作数之间不因该加空格,比如:负号(-)、自增(+)和自减(-)。例如:a += c + d;a = (a + b) / (c * d);n+;printSize(size is + foo + n);4、for 语句中的表达式应该被空格分开,例如:for (expr1; expr2; expr3)5、强制转型后应该跟一个空格,
27、例如:myMethod(byte) aNum, (Object) x);myMethod(int) (cp + 5), (int) (i + 3) + 1);一.9 异常处理系统中捕获的异常,在无法采取补救措施或补救措施失败后,一律不允许单独处理异常,全部要向上级代码抛出,由系统统一处理。系统提供了通用的异常封装类BaseException和在代码中程序员需把捕获到的具体异常和相应的异常描述代码一同封装入BaseException中,“向外”抛出,最终由系统统一处理。当在业务层代码(handler)中有异常发生时,需在异常try/catch的catch块中创建BaseException,将捕获
28、到的具体异常封装入BaseException,并将BaseException向外抛出至servlet中,交由上级代码统一处理,并记录详细的日志信息。例如:trycatch(IOException e) log.error(系统发生异常:无法进行XXX操作,e); throw(new BaseException(IErrorCode.IO_Exception,e); 当在逻辑控制层代码(servlet)中有异常发生,或有异常被抛出至servlet中时,不允许在servlet中出现try/catch块对产生的异常进行处理。servlet中的方法一律将异常“向外”抛出,由系统级代码统一处理。 例如:
29、protected void performTask()throws NumberFormatException一.10 其他规范1、限制外部包的使用如果需要使用一个外部包需要听取项目经理的意见。在项目经理批准以前,严禁擅自使用一个外部的包;2、对于只有一行的方法体,可以和方法声明写在一行上;3、在类内部尽量不要定义main方法,请使用TestMain运行待测试的类,如果已经定义了, 那么它应该写在类的底部;4、程序中用到的资源,比如文件流、数据库连接等,要遵循哪里获取哪里释放的原则;5、PrintStream 已经被不赞成(deprecated)使用,用 PrintWrite 来代替她。JSP规范一.11 JSP文件名命名规则以功能名称+操作名称作为JSP文件名称,例如用户管理的用户维护的功能名称为USER_MANAGE_MAINTAIN,当前操作名称为增加,则该JSP的名称为userManageMaintainAdd.jsp操作名称一览表:操作名称代码增加Add修改Modify明细Detail删除Delete查询Search审核操作Audit列表List一.12 JSP头格式JSP头部一般需要遵循以下格式:/ jdk标准包 / java扩展包 /使用的
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1