后台开发规范v10.docx
- 文档编号:3331544
- 上传时间:2022-11-21
- 格式:DOCX
- 页数:12
- 大小:68.53KB
后台开发规范v10.docx
《后台开发规范v10.docx》由会员分享,可在线阅读,更多相关《后台开发规范v10.docx(12页珍藏版)》请在冰豆网上搜索。
后台开发规范v10
前言
代码是程序员的生命,是程序员日日夜夜心血的凝结,请大家像爱惜自己的眼睛一样来合理编写程序。
命名规范
1.所有工程,包,类,接口,方法,属性,变量,参数均使用英文单词进行命名,命名必须见命知意,避免如temp_1,x,y,z之类的无意义的名字,要像给自己孩子起名一样慎重。
1.1包、变量、属性、参数命名:
第一个单词首字母小写,后面的单词根据你的需要首字母依次大写,举例如下:
如包名:
com.yihaodian.backend.sso.backOperator,
变量名、参数名:
backOperatorDto,backOperatorName等等
1.2方法命名:
DAO层如果是单条查询请用find开头,如:
findBackOperatorById,查询集合通过find*list开头,findMerchantListByOperatorId,新增用add开头,更新用update开头,删除用delete开头,Service层方法命名根据具体业务来,见命知意,如取消订单,cancelSo。
1.3类命名:
Action层以**Action结尾,Service层以**Service结尾,实现类以**ServiceImpl结尾,Dao层以**Dao结尾,实现类以**DaoImpl结尾。
2.所有包名使用必须使用com.yihaodian.backend前缀,所有项目使用com.yihaodian.backend.[projectname],projectname是项目的开发代号或缩写。
参考下图,比如backend-bpm,缩写就是bpm,工程包前缀就是
com.yihaodian.backend.bpm
3.所有新加的工程必须是标准的maven工程,maven版本是3.x,工程名称一律以backend-*开头,如backend-erp,backend-cs。
4.配置文件命名,spring框架前缀为spring-*,struts2前缀为struts-*,ibatis前缀为ibatis-*。
5.单元测试包名命和路径必须要和每个单元测试对应的方法,如:
com.yihaodian.backend.sso.service.impl.CategoryServiceImpl.findCategoryAllFirstLevel方法对应的单元测试和路径为com.yihaodian.backend.sso.service.impl.CategoryServiceImplTest.testFindCategoryAllFirstLevel.
下图为一个后台maven工程参考
注释规范
概述
代码中为什么要包含注释?
1.别人要调用你的程序中的公共接口,对这部分进行文档描述,使别人能够正确而有效的使用它。
2.除了自己,别人要阅读和维护你的代码。
为了使代码更容易维护,首先要使代码更易于理解,才能在理解的基础上进行维护。
对这些代码进行文档描述,将使这个过程变得更加容易。
如果代码可读性很好,命名表意丰富,清晰,一般不需要特别多的注释。
对于类,主要着重要描述它的职责,即它能干什么,对于复杂的算法实现,应该使用内部实现注释,说明算法的主要思路,对于长方法(避免使用长方法,100行以上就被认为是长代码),要让阅读代码的人比较容易的明白方法实现的主要流程。
反之,对于一看就懂的方法,则不需要进行注释,比如get/set方法,避免注释泛滥。
一般原则
1.代码应该和注释保持同步。
2.注释尽量简洁,尺度没有准确的定义,大部分人能明白即可,可以将自己的代码给同事看看。
注释内容
/***
*后台用户所有中间表操作的门面类
*@create-time2011-11-15
*@authorbackend
*
*/
publicclassBackOperatorFacadeServiceImplimplementsBackOperatorFacadeService{
privatestaticfinallongserialVersionUID=1380602554886673288L;
privateBackOperatorDaobackOperatorDao;
privateBackOperatorMerchantDaobackOperatorMerchantDao;
privateCacheServicecacheService;
Loglogger=LogFactory.getLog(BackOperatorFacadeServiceImpl.class);
/**
*根据用户Id查询所有用户的角色Id集合
*@parambackOperatorId
*@return
*@throwsException
*@modified-bybing
*@modifed-time2011-11-20
*/
publicList
if(null==backOperatorId)
thrownewSsoBizException(ExceptionCode.PARAM_IS_NULL,PropertiesUtils.getValueFromException(ExceptionCode.PARAM_IS_NULL));
try{
returnthis.backOperatorDao.listRolesByBackOperatorId(backOperatorId);
}catch(Exceptione){
e.printStackTrace();
}
returnnull;
}
复杂的业务逻辑一定要针对每个操作进行注释
编码规范
Ø约束原则
1.不允许提交编译报错和带黄色警告的代码-胡明贡献
2.对于静态方法,应该使用类名去使用,不应该用实例去引用,主要是为了体现更多的语义。
3.对一些基本数据类型和不太可能通过继承进行扩展的类,应声明为final,提高效率。
4.类和方法的粒度保持适中,保持类的规模尽量短小,职责单一。
小类有很多好处,易于设计,易于测试,易于理解。
同样方法也要尽量的小,每个方法尽量不要超出100行。
5.单一职责,如果一个类有多于一种的职责,当需求变化时,类的职责就要发生变化,而因此就会引起引用该类的代码发生改变,职责越多,这个类就容易跟更多的类产生耦合关系,而且改变一个职责,可能会影响到另外一个职责的履行。
6.编写代码前,先编写注释(避免想到哪写到那,把逻辑写完整了再去写代码)。
总的来说尽量保证类和方法职责单一,支持可扩展。
Ø具体约束
1.inttempValue;
tempValue=maxValue;
tempValue=minValue;
tempValue=anotherValue;
tempValue在生命周期内表示了各种各样的意图,增加理解代码的难度。
应该为每个独立概念定义单独的变量:
inttempMaxValue;
inttempMinValue;
inttempAnotherValue;
2.仅仅循环控制变量才能出现在for()循环中
sum=0;
for(i=0;i<100;i++){
sum+=value[i];
}
//避免:
for(i=0,sum=0;i<100;i++){
sum+=value[i];
}
3.循环变量应靠近循环体初始化(延伸开来就是变量定义地方要和使用地方尽量的靠近)
isDone=false;
while(!
isDone){
...
}
//避免
isDone=false;
...
...
while(!
isDone){
...
}
4.避免长的布尔表达式,应换成多个更容易理解的表达式。
booleanisFinished=(elementNo<0)||(elementNo>maxElement);
booleanisRepeatedEntry=elementNo==lastElement;
if(isFinished||isRepeatedEntry){
...
}
//避免
if((elementNo<0)||(elementNo>maxElement)||elementNo==
lastElement){
...
}
5.不要在条件语句中执行方法,以提高可读性
InputStreamstream=File.open(fileName,"w");
if(stream!
=null){
...
}
//避免
if(File.open(fileName,"w")!
=null)){
...
}
6.代码缩进,应该使用4个空格为一个单位进行缩进。
publicStringinvoke()throwsException{
....StringprofileKey="invoke:
";
....try{
........UtilStack.push(profileKey);
........if(executed){
............test=true;
.......}
....catch{
....}
}
7.常见的逻辑判断应该放到service层处理,比如数据为空判断,数据不合理判断,数据异常判断,都放到service层,复杂的业务逻辑一定要放在service层,DAO层和Action层只是简单的调用,异常处理、日志处理、事务处理也统一放到service层。
怎样保证业务层精简请看上面“编码规范->约束原则第3条”。
8.If-else不应嵌套太多,不能超过三层,如果嵌套太多应该考虑调整你的逻辑了或者换种实现方式,比如:
命令模式等等。
9.嵌套循环不能超过三层
10.坚决避免循环依赖,工程和代码之间一定不能有循环依赖
11.数据库连接,读写流等等一定要关闭,常见情况是放到finally关键字里面处理,如:
OutputStreamos=null;
try{
//开启一个输出流
os=newFileOutputStream("somefilepath");
}catch(FileNotFoundExceptione){
e.printStackTrace();
}finally{
try{
//关闭一个输出流
If(os!
=null){
os.close();
}
}catch(IOExceptione){
e.printStackTrace();
}
}
12.日志处理,一般的异常情况都需要增加log4j日志,尽量不要用“System.out.println()”,log4j的常见级别为debug,info,warn,error。
通过log4j记录日志应该判断当前日志级别是否可用,减少不必要的IO操作。
如:
Loglogger=LogFactory.getLog(RoleAction.class);
if(logger.isErrorEnabled())
logger.error("someerrors");
if(logger.isDebugEnabled())
logger.debug("somedebugs");
13.习惯使用apache的工具类做常见判断,apache常见的工具类有StringUtils,CollectionUtils等等,存放的jar包commons-lang.jar,common-collections.jar。
14.敏感的数据更新记得加上乐观锁,有并发同步问题记得加锁。
15.并发量很大的业务逻辑考虑用线程池实现。
欢迎补充。
。
。
。
外部接口规范
1.项目间接口调用不应出现循环依赖调用,两个工程存在接口间调用应该将共有的接口和数据传输对象分装成公用jar包。
如:
客服系统backend-cs和工作流系统backend-bpm同时依赖公有的backend-bpm-api,backend-bpm-api存放是公用的dto和业务类接口。
2.敏感数据接口调用考虑数据加密和签名,比如:
后台数据加密目前使用的对称加密算法Base64,签名用的算法是MD5,密钥请尽量复杂包括数字字母和特殊字符。
3.一号店内部项目接口调用请考虑hessian,对外网公布的接口请考虑Webservice。
4.服务端并发量大的接口请考虑异步调用,比如使用线程池等等。
5.接口调用的客服端和服务端请做好异常日志处理及相关异常处理,日志记录最好不要用主库的表,避免给主库造成太大的压力。
6.暴露接口的服务端一定要有接口文档,并且要有详细的接口代码注释。
异常处理规范
程序其实由若干个主程序和n个异常流组成,异常流发生于主程序里面,try里面是主程序,catch里面异常流,一个标准的trycatch的格式如下:
try{
程序代码
}catch(异常类型1异常的变量名1){
程序代码
}catch(异常类型2异常的变量名2){
程序代码
}finally{
程序代码
}
合理的定义和处理异常可以方便开发人员查找问题,一个工程里面应该针对每种情况定义不同的异常,如:
参数不合理,数据不存在,业务接口异常等等,举个例子,用户不存在我会定义一个OperatorNotExistsException,当查询用户不存在时抛出此异常,参数为空或者不符合某些规定的条件时抛出IllegalArgumentException,所有的异常处理都应该放在业务层处理。
SQL编写规范
一个业务sql最好不要超过3张表(超过3张表需要sql管理委员会确认),少用like,in,order等关键字
1.不等于统一使用"<>"
Oracle认为"!
="和"<>"是等价的,都代表不等于的意义。
为了统一,不等于一律使用"<>"表示。
2.使用表的别名
数据库查询,必须使用表的别名,方便阅读。
3.禁止使用select*
5.减少子查询的使用
子查询除了可读性差之外,还在一定程度上影响了SQL运行效率。
请尽量减少使用子查询的使用,用其他效率更高、可读性更好的方式替代。
6.合理的使用索引
7.主表使用逻辑删除(is_deleted)
8.主表必须使用状态字段creator,modifier,update_time,create_time
9.少用clob等大字段,如果必须要用请拆分出单独的表
10.大表和附属表应该分开来,如:
产品表product是一张大表,组合产品、序列产品等特殊的附属表不应该放到大表中,应该单独建表。
11.选择最有效率的表名顺序
ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表drivingtable)将被最先处理。
在FROM子句中包含多个表的情况下,必须选择记录条数最少的表作为基础,当ORACLE处理多个表时,会运用排序及合并的方式连接它们。
首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行排序;
然后扫描第二个表(FROM子句中最后第二个表);
最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并
例如:
表product16,384条记录
表category5条记录
选择category作为基础表(最好的方法)
selectcount(*)fromproduct,category执行时间0.96秒
选择product作为基础表(不佳的方法)
selectcount(*)fromcategory,product执行时间26.09秒
如果有3个以上的表连接查询,那就需要选择交叉表(intersectiontable)作为基础表,交叉表是指那个被其他表所引用的表
例如:
back_operator_category表描述了catgory表和back_operator表的交集
select*
fromback_operatorbo,catgoryc,back_operator_categoryboc
wherebo.id=boc.back_operator_idandc.id=boc.category_id
将比下列SQL更有效率
select*
fromback_operator_categoryboc,back_operatorbo,catgoryc
wherebo.id=boc.back_operator_idandc.id=boc.category_id
12.WHERE子句中的连接顺序
ORACLE采用自下而上的顺序解析WHERE子句
根据这个原理,表之间的连接必须写在其他WHERE条件之前,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.
13.减少访问数据库的次数
当执行每条SQL语句时,ORACLE在内部执行了许多工作:
解析SQL语句,估算索引的利用率,绑定变量,读数据块等等
由此可见,减少访问数据库的次数,就能实际上减少ORACLE的工作量.
14.使用exists(notexists)代替in(notin)
15.使用PrepareStatement,避免使用拼凑sql,对应ibatis,就是要用#变量#,避免使用$变量$
ERD设计规范
一个合理的ERD设计文档需要表机构设计、流程图、时序图,尽量避免长篇大论描述,用伪代码代替。
表结构设计请统一用下表
字段名
字段类型
是否非空,如果可以为空就不填
默认值
描述
PRODUCT_CNAME
VARCHAR2(1000)
notnull
产品名称
IS_DELETED
NUMBER
(1)
0
是否逻辑删除
CODEREVIEW规范
一个大项目(超过20人日)最少需要安排2次codereview,更长周期的可以安排更多,codereview一般都需要domainleader,teamleader参加,如果他们有事,需要开发人员交叉review,如果是交叉review需要记录问题点,改进方案并群发邮件到backend组。
考虑到武汉和上海两天的因数,尽量简化流程,武汉team的codereview,武汉的teamleader必选,刘晶和上海的开发人员作为可选,上海类似
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 后台 开发 规范 v10