NC程序开发规范用友软件股份有限公司提高代码可读性以及相关资源的可维护性增加程序的可理解性,实现代码及文档的编程目标使软件的质量能够得到控制,实现软件产品的顺利交付形成基本的编程原则,避免常见错误降低软件在其整个生命周期的开发和维护成本标准化的开发规范和规范过程能够提高整个Team的开发效率意义主要内容文件规范命名规范注释规范编码规范文件规范-目录结构NC产品的主要目录结构ierp/bin:与整个产品相关的配置文件都存放在该目录,如日志配置文件logger-confing.propertiesmodules:NC产品模块存放的目录,下面的所有模块在系统启动时得到加载modules/<模块名>:某个模块的目录,模块名必须是小写的英文字母,在能表达意义的基础上尽量的短modules/<模块名>/META-INF/module.xml:必须存在,配置模块的一些通用属性,如名称,描述,classloader等,注意名称必须与模块名称同名文件规范–目录结构NC产品的主要目录结构modules/<模块名>/lib:模块公开的API类,如接口,接口相关的VO等,放JAR包modules/<模块名>/classes:模块公开的API类,如接口,接口相关的VO等,放带目录的.class文件等,用于补丁modules/<模块名>/META-INF/lib:模块私有的代码,如DMO,业务实现等,放JAR包modules/<模块名>/META-INF/classes:模块私有的代码,放带目录的.class文件等,用于补丁modules/<模块名>/extension/lib,classes:用于二次扩展的公开的API文件规范-目录结构NC产品的主要目录结构modules/<模块名>/extension/META-INF/lib,classes:用于二次扩展的私有的APImodules/<模块名>/client/lib,classes:用于从目标上来说不属于公共的API,但是客户端用到的代码webapps/nc_web:NC产品的web应用hotwebs:下面放其他的web应用,如hrss,lfw等resource:存放与整个产品相关的资源,如产品的多与资源lib,classes,external/lib,classes:由平台维护和提供的类库,不允许第三方调整文件规范–资源文件资源文件一般以.properties作为文件结尾资源文件的编码建议采用UTF-8编码资源文件的注释以#开头资源文件的资源的id在整个产品中保持唯一多语资源夫和多语资源的的NC规范文件名建议英文和数字和下滑线组成,具有一定意义模块级别的资源文件放在模块下的resource目录文件规范-XML一般以xml文件结尾,对于模块的组建配置文件,可以有module,upm,usm三种后缀,其中upm,usm在5.5后支持文件必须以UTF-8编码符合schema的要求,如web.xml,必须符合j2ee对web应用配置文件的schema要求文件的命名需要有一定的意义,尽量简短文件规范–图片图片采用压缩格式,在不影响外观的条件下尽量的小Web应用中,各个产品模块的图像文件放在本模块的资源目录下面命名规则–基本方针字符集在26个英文字母、0到9的阿拉伯数字和下划线之中,并尽量的只采用字母命名需要有一定的意义,推荐采用问题域中的术语命名,使命名在一定程度上是自描述的命名尽量的短,如果命名太长,可以采用别名的方式,或者缩写来简化命名。缩写一定要有的意义,而且需要在整个项目中维护这些缩写的意义名称缩写的规则(对于类名、字段名、变量名称、模块名称等适用)删除所有的原音字母,压缩重复字母。如button,缩写为btn,如发生命名冲突,则在某一缩写中保留原音。如batton,为了不与button冲突,缩写为batn不要用前导下划线,也不要在命名的末尾用下划线命名规则–常量所有的字符都必须大写。采用有意义的单词组合表达,单词与单词之间以“_”下划线隔开。命名尽量简短,最好不超过16个字符尽量采用常量,除非惯例,不直接使用值,如在for循环中初始化变量时可直接用-1,0,1这些常量publicfinalintMAX_SIZE=120;publicfinalintMAX_WIDTH=100;publicfinalStringPROPERTY_NAME="menu"publicfinalintMAX_SIZE=120;publicfinalintMAX_WIDTH=100;publicfinalStringPROPERTY_NAME="menu"命名规则-变量变量的命名包括实例变量,静态变量,函数参数的命名,一般以名词形态存在避免在命名中采用数字,除非命名意义明确,程序更加清晰,对实例变量的命名中不应该有数字第一个单词全部小写,后续的每个单词首字母大写(特殊单词除外,如URL)命名尽量简短,最好不超过16个字符除了生命周期很短的临时变量外,避免采用单字符作为变量名,实例变量的命名不要用单字符。常用的单字符变量如整型用i、j、k、m、n字符型用c、d、e,坐标用x、y、z在某些情况下,变量可以加上类型前缀,类型前缀必须是小写,并与变量名称的实体部分没有任何间隔,实体部的每个单词都是首字母大写,其余字母小写(特殊单词除外如URL),类的全局变量建议使用,一般的类型前缀如下:命名规则-变量类型前缀类型例子bBoolean,booleanbsinglefFloat,floatfpricedtDate,CalendardtFromcCharacter,、charcinputobjObjectobjUserstrString,StringBufferstrFileNamei整型数iCountbtn按钮btnSubmiterr错误errCodepublicintwidth;publicStringfileName;publicstaticApplicationContextcontext;publicintwidth;publicStringfileName;publicstaticApplicationContextcontext;命名规则–方法命名多数为动词结构采用有符合问题域意义的单词或单词组合,第一个单词小写,后续的每个单词首字母大写(特殊字除外如URL),没有特别理由不用下划线作为分隔符在Java中对属性方法命名遵循JavaBean的标准getter方法:get+属性名,对boolean型采用is+属性名,有些特定的属性名用has,can代替is可能更好setter方法:set+属性名StringgetName();booleanisStopped();voidconnect();StringgetName();booleanisStopped();voidconnect();命名规则–类和接口名称一般为名词形态采用有符合问题域意义的单词或单词组合,每个单词的首字母大写(特殊如URL)业务接口的第一个字母建议为I对与继承ValueObject对象的类,以VO结尾名称长度不超过16个字符,必要采用简写publicclassFiugrepublicinterfaceFiugreContainerpublicclassStdFigure//std为Standard的缩写publicclassFiugrepublicinterfaceFiugreContainerpublicclassStdFigure//std为Standard的缩写命名规则–包命名采用逻辑上的层次结构,降低包依赖复杂度产品模块对外的接口定义放在nc.itf.模块名.xx服务的实现类nc.impl.模块名.xx后台业务类代码nc.bs.xx值对象命名:nc.vo.模块名UI层命名:nc.ui.模块名命名简短,常采用缩写包名所有字符都为小写不要用java,javax作为自定义包的前缀注释–基本原则注释应该使代码更加清晰易懂注释要简单明了,只要提供能够明确理解程序所必要的信息就可以了。注释太复杂说明程序需要修改调整,使设计更加合理注释不仅描述程序做了什么,还要描述为什么要这样做,以及约束对于一般的getter、setter方法不用注释生成开发文档的需要用中文编写注释不能嵌套注释–文档注释Javadoc用它来产生代码的文档(/**…*/),可以多行用来对类、接口、成员方法、成员变量、静态字段、静态方法、常量进行说明为了可读性,可以有缩进和格式控制(如采用html的元素,转移字符文档注释常采用一些标签进行文档的特定用途描述,用于帮助Javadoc产生文档标签用于目的@author类/接口描述代码的编写人,每个编写人对应一个条目@deprecated类,成员方法说明该段API已经被废除@exceptionnamedescription@throwsnamedescription成员方法描述方法抛出的异常每个异常一个对应一个这样的标签@returndescription成员方法描述成员方法的返回值的意义@since类/接口、成员方法描述该段API开始的时间@seeClassName类/接口、成员方法、成员变量用于引用特定的类描述,一般ClassName用包括包名的全名@seeClassName#memberfunction类/接口、成员方法、成员变量用于引用特定的类的成员方法的描述,一般ClassName用包括包名的全名@versiontext类/接口版本注释-行注释一次只能注释一行(//)用来简短的描述某一个局部变量,程序块的作用注释-块注释进行多行的复杂注释一般用来对程序块、算法实现、类的实现进行说明为了可读性,可以有缩进和格式控制。一般在行注释不能满足注释需要的时候采用注释-类和接口采用文档注释说明类设计的目标,完成什么样的功能
如何使用该类,包括环境要求,如是否线程安全,并发性要求,以及使用约束已知的BUG描述类的修改历史:
修改人+日期+简单说明@author作者、@version版本,@see参照,@since开始版本等信息如版本就以当时开发的NC产品的应用版本号为准注释-类和接口/***ThisclassprovidesdefaultimplementationsfortheJFC
Action*interface.Standardbehaviorslikethegetandsetmethodsfor*
Actionobjectproperties(icon,text,andenabled)aredefined*here.Thedeveloperneedonlysubclassthisabstractclassand*definethe
actionPerformedmethod.*
*Warning:*Serializedobjectsofthisclasswillnotbecompatiblewith*futureSwingreleases.Thecurrentserializationsupportisappropriate*forshorttermstorageorRMIbetweenapplicationsrunningthesame*versionofSwing.AfuturereleaseofSwingwillprovidesupportfor*longtermpersistence.**@version1.4102/02/00*@authorGeorgesSaab*@seeAction*/注释–变量成员变量、类静态变量采用文档注释,对成员变量的注释通常包括变量的意义变量的合法值域对并发访问的限制局部变量,如算法相关的变量采用块或行注释参数变量注释一般用文档注释,并且用@param来说明为参数,一般包括:参数的用途对参数值范围的要求/***Web.xml文件中configServlet参数的UIAPP.xmlinitparam*/publicfinalstaticStringAPP_CONFIG=“aaa.uiapp”;voidfunc(){inti;//用于循环计数}注释–方法描述函数的功能,对成员方法,静态方法一般采用文档描述,特别是公开的方法方法注释一般包括:描述方法完成什么样的功能,方法的目标,用该方法的原因描述方法的使用方法,包括使用的环境要求,如前置条件,后置条件和并发性要求描述已知的bug描述方法的修改历史:修改人+日期+简单说明(<修改人+日期+简单说明>)@paramcelementstobeinsertedintothislist.(参数说明)@returntrueifthislistchangedasaresultofthecall.(返回值说明)@throwsNullPointerExceptionifthespecifiedCollectionisnull.(异常说明)@see如果重载方法必须参考父类的方法注释–方法/***构造JdbcSession,该JdbcSession会从指定的DataSource中得到连接**@paramdataSourceName*数据源名称*@throwsDbException*如果访问数据源出错则抛出DbException*/publicJdbcSession(StringdataSourceName)throwsDbException{注释–算法算法描述指在实现级别的描述注释,如在方法内的注释般采用块/行注释,对于简短的描述采用行注释,不要用文档注释注释的主要内容包括:某些局部变量的意义和用途复杂的控制结构的注释,如循环,分枝,条件表达式。说明控制所要达到的目标复杂的代码段的描述,说明代码完成的功能,以及为什么这样做注释–文件头放在文件的最开头一般用来注释文件的版权和历史信息在Jaava文件中采用块注释修改记录一般格式为:<修改人>+<修改日期>+<->+<修改描述>。编码规范–基本规则一个程序文件最好不要超过2000行尽可能缩小对象的作用域,这样对象的可见范围和生存期也都会尽可能地小一个方法所完成的功能要单一,不同的功能封装为不同的方法尽可能的处理异常或转换异常,不要一味的包装异常如果对象在某个特定范围内必须被清理(而不是作为垃圾被回收),请使用带有finally子句的try块,在finally子句中进行清理编码规范–基本规则一个程序文件最好不要超过2000行尽可能缩小对象的作用域,这样对象的可见范围和生存期也都会尽可能地小一个方法所完成的功能要单一,不同的功能封装为不同的方法尽可能的处理异常或转换异常,不要一味的包装异常如果对象在某个特定范围内必须被清理(而不是作为垃圾被回收),请使用带有finally子句的try块,在finally子句中进行清理编码规范–基本规则对于把一些逻辑相关的类组织在一起,可以考虑把一个类的定义放在另一个类的定义中,这种情况推荐使用内部类(比如界面层中的事件响应等)。内部类拥有所有外围类所有成员的访问权对成员变量的访问最好通过getter/setter方法,这样能够保证访问的合法性,以及代码调整优先选择接口而不是抽象类或具体类。如果你知道某些东西将成为基类,你应当优先把它们设计成接口;只有在必须放进方法定义或成员变量时,才把它修改为具体或抽象类。接口只和客户希望的动作有关(协议),而类则倾向于关注实现细节编码规范–基本规则在处理可变String的时候要必须使用StringBuffer类,可变范围在5次以内可以使用String使用java标准库提供的容器,优先选择ArrayList来处理顺序结构,选择HashSet来处理集合,选择HashMap来处理关联数组,选择linkedList来处理堆栈和队列,它对顺序访问进行了优化,向List中间插入与删除的开销小,但随机访问则较慢。当使用前三个的时候,应该把他们向上转型为List、Set和Map,这样就可以在必要的时候以其它方式实现编码规范–基本规则数组是一种效率最高的存储和随机访问对象引用序列的方式,但是当创建了一个数组对象,数组的大小就被固定了,如果在空间不足时再创建新的数组进行复制,这样效率就比ArrayList开销大了。所以必须明确使用场景。尽量使用”private”、”protected”关键字采用类而不是对象引用静态变量和方法使用UFBoolean必须采用UFBoolean.valueof(true|false|y|n|Y|N)的形式进行构造编码规范–基本规则禁止后台业务代码使用如下代码try{something()}catch(Exceptionex){}thrownewException()编码规范–类每个方法(包括构造与finalize)都是一个段。多个变量声明按照逻辑共同组成一个段,段与段之间以空行分隔编写通用性的类时,请遵守标准形式。包括定义equals()、hasCode()、toString()、Clone(实现Cloneable接口),并实现Comparable和Serialiable接口对于设计期间不需要继承的类,尽量使用final类的结构组织,一般按照如下的顺序1.常量声明2.静态变量声明3.成员变量声明4.构造函数部分5.Finalize部分6.成员方法部分7.静态方法部分编码规范–变量对成员变量,尽量采用private每一个变量声明/定义占一行(参数变量除外)局部变量在使用前必须初始化,一般在声明时初始化变量的声明要放在程序块的开始位置(for语句除外)数组的申明采用<数据类型[]+变量名>方式如:避免变量的定义与上一层作用域的变量同名inta;intb;voidmyMethod(){intint1=0;//beginningofmethodblockif(condition){intint2=0;//beginningof"if"block}for(inti=0;i<100;i++)}char[]buffer;编码规范–方法对成员方法,不要轻易的采用public的成员变量。主要的修饰符有public,private,protected空方法中方法声明和函数体可都在一行。如:voidfunc(){}方法和方法之间空一行方法的文档注释放在方法的紧前面,不能空一行避免过多的参数列表,尽量控制在5个以内,若需要传递多个参数时,当使用一个容纳这些参数的对象进行传递,以提高程序的可读性和可扩展性方法中的循环潜套不能超过2层对于设计期间不需要子类来重载的类,尽量使用final每个方法尽量代码行数尽量不要超过100行(有效代码行,不包括注释),但必须保证逻辑的完整性编码规范–其他在与常数作比较时常数放在比较表达式的前面return语句中,不要有复杂的运算switch语句,需要一个缺省的分支if("simpleCase".equals(obj)){...}if(null==obj){...}