后端代码规范

1. 命名规范

1.1 总体命名规则

1. 名字含义要明确,做到见名知义,如: User,Customer
2. 尽量少用缩写,必须确保能让人看懂含义。

1.2 变量名

1. 小驼峰式命名,变量名首字母必须为小写字母,不使用 “_” 作为变量名(包括成员变量)开头
2. 尽量使用英文作为变量名, 若使用汉语拼音,必须注释清楚
3. 正确:userName   错误:UserName,_UserName,username

1.3 常量名

1. 常量名必须全部为大写
2. 各单词必须以下划线分开,以便区分
3. 对于枚举类常量,如:状态,尽量使用Enums定义 如

public enum ApplStatus implements ResponseService{ APPROVING("AP","申请中"), PASSS("PS", “已通过”), REJECT("RJ", “已拒绝”) }

1.4 包名

1. 包名必须小写
2. 包名尽量简洁,一个单词或缩写
3. 包名不能以数字开头,尽量只包含字母
4. 所有系统包命名须在:com.qihoo.finance,如:com.qihoo.finance.msf;maven依赖,groupId:com.qihoo.finance.xxx,artifactid: xxx-app, xxx-api等

1.5 类名

1. 大驼峰式命名,即单词首字母大写,如:UserService
2. 接口名不加前缀
3. 抽象类名以Abstract开头
4. 接口实现类名必须加上Impl,以Impl结尾,如:UserServiceImpl

2. 排版规范

1. 缩进必须用space,不能使用tab键,可以在eclipse或其他开发工具配置一个tab用4个space代替。
2. 单行字符数不超过120个
3. 开发工具建议使用intellij Idea,工具稳定性好,智能化,内存消耗稳定。
4. 其他?可以使用工具自动格式化功能

3. 注释规范

1. 类名,功能方法接口名称必须有注释

2. 复杂代码逻辑必须有注释

3. 代码注释不超过一行使用'//',超过一行使用‘/* */’

4. 代码提交规范

1. 原则上完成一个完整功能并自测无异常后,方可checkin代码,必须保证无编译报错

2. 提交代码必须写注释,能够完整描述本次提交变更的内容

例如:

缺陷/需求编号:(如果有)

修复/提交说明:修复自动获取实例编号并发启动获取失败问题/增加kryo序列化扩展,并设置为dubbo协议默认的序列化组件

5. 业务开发规范

5.1 包路径规范

1. 按公司域名,系统,子系统[模块]方式命名, 如:com.qihoo.msf.app.cust
2. 在子系统/模块下,业务开发一般包含以下几个包:
    service         定义服务接口
    domain/entity   定义实体类
    Exception       定义异常类已经异常错误定义
    dao             数据访问层

5.2 配置文件路径规范

配置文件统一规划在 src/main/resources 目录下,按照配置文件类型可以划分为一下几个子目录
    spring          spring相关配置文件,可以根据组件或模块拆分为几个文件,启动application.xml默认加载配置文件夹
    properties      存放*.properties文件夹,与环境相关的配置在此类文件中,系统会初始化加载,测试生产放在特殊路径,与实例部署无关,以达到配置分离目的。
    mybatis/mappings/子模块  Mybatis的Mapper文件,分模块存放
    dubbo-service/[consumer/privider]-service    服务注册配置,consumer-service文件夹存放所有依赖的外部服务注册,按依赖系统分文件,如:loan-service.xml,customer-service.xml;provider-service文件夹存放实例提供的服务配置。
    META-INF/dubbo/internal   dubbo扩展包,对dubbo服务扩展在此注册,dubbo基于spi扩展。

5.3 MAVEN项目规范

1. maven命名规则,com.qihoo.系统名
2. 任何一个子系统的服务接口定义和服务实现必须划分为两个项目,如:loan-provider,loan-api
    a. 服务接口项目主要包含以下几个模块:
        service         接口定义类
        domain/entity   接口相关实例定义
        exception       异常定义
    b. 服务实现项目主要包含:
        业务逻辑实现
        dao接口定义及实现

5.4 测试代码编写规范

1. 测试相关代码必须在 src/test/java 目录下
2. 测试相关的配置必须在 src/test/resources 目录下
3. 测试代码必须采用Junit方式编写,基础加载读取数据可以继承SpringTestCase即可
4. 测试案例必须有断言结果,如:Assert.assertEquals("Error20001", actualResult);

5.5 异常及错误编码规范

5.5.1 异常说明

1. 异常可分为业务异常和系统异常,系统异常的基类为SystemException, 业务异常的基类为BusinessException。父类为ServiceException
2. 业务逻辑校验异常,抛出BusinessException
3. msf服务体系内所有暴露服务接口定义抛出ServiceException,外部系统调用服务,通过状态码返回异常信息
3. 所有的错误代码采用Enum定义

5.5.2 错误代码命名规范

1. 系统异常代码由7位组成, 规则为:S+3位系统代码+3位数字编码,如:SAPV001   服务调用超时
2. 业务异常代码由7位代码组成,规则为:B+3位系统代码+3位数字, 如BAPV000   请求参数为空
3. enum常量命名格式为:模块代码+‘_’+异常变量,异常变量含义与中文一致,命名含义清晰,见字识义
4. 错误代码按模块连续编码,不同模块之间起始位数字不一样,如下图所示:

5.6 日志规范

1. 日志统一采用log4j2,是log4j的升级版本,性能是log4j的10倍,暂时采用默认的log4j
2. Logger的获取方式统一采用class的方式,使用dubbo提供的Logger,LoggerFactory类,如:
    private static final Logger logger = LoggerFactory.getLogger(UserService.class);
3. 业务关键环节必须打印日志
4. 外部接口调用必须打印日志,并统计接口调用耗时,以便统计趋势图
5. error级别以上的日志,必须记录关键业务信息,如方法的入参,错误发生时的变量现场,以便回溯追踪问题。
6. 禁止打印密码等敏感信息

5.7 事务规范

事务统一在spring配置文件中声明,按照方法匹配方式,服务开发只需要遵守命名规则即可
1. 不允许通过注解的方式定义事务,因事务源切换,事务控制机制等不易统一管理
2. 外部接口必须禁止在事务中
3. 禁止长事务,长事务切分为多个短事务,最好dml集中使用事务
4. 禁止嵌套事务,嵌套事务不易掌控
5. 事务必须显式声明,方法名匹配方式,‘*Trx’,‘\*NewTrx’,方法默认非事务运行

6. 系统设计规范

6.1 接口设计规范

1. 一切基于接口开发,提供业务逻辑服务必须提供接口
2. 接口方法参数超过3个,需要转换为dto属性,对象入参
3. 对外提供服务接口JSON返回结构[状态,错误代码,错误描述,数据]
4. Module内部服务接口类名以Service结尾,接口方法细粒度;对外提供接口类名以Facade结尾,接口方法定义粗粒度,禁止跨域调用DAO。
5. Service实现内部细粒度业务逻辑,Service不能跨域调用Service。
6. Façade层负责对外提供粗粒度功能方法,采用模板设计模式方法,实现仅包括:1. 入参校验;2.入参转换、清洗;3. 粗粒度业务功能流程控制(具体实现下沉到Service层,超过5个步骤应考虑下沉到Service);4.出参数据转换。
7. Facade调用:不同发布单元接口(Façade)调用,封装成内部Service方式,并实现入参出参记录,耗时统计等,系统内部只与内部Service交互;系统内不同待拆分模块之前接口调用Façade。
8. 尽量使用缓存:配置类数据使用内存(一级)缓存;业务类数据使用redis(二级)缓存
9. 服务必须设计为无状态服务,即,请求可以在任何实例完成处理
10. 服务设计为基于https短连接服务
11. 服务设计可并发执行、幂等性
12. 禁止使用Map作为入参出参,会增加接口复杂度,容易造成序列化、反序列化失败
13. 接口入参出参禁止删除字段、修改参数字段名,
14. 接口可以新增入参,出参;如果接口逻辑不兼容修改,必须使用版本号,并通知下游修改
15. 接口默认使用dubbo协议,单次请求入参、出参不能超过100k,否则必须更换hessian协议

6.2 领域设计规范

1. 服务类基于业务领域模块划分,划分原则可以与业务表对应
2. 尽量减少表连接,杜绝两个业务领域的表连接
3. 禁止大表连接(超过100w数据)
4. 禁止在SQL语句中使用1=1
5. 禁止批量数据用in关键词分组排序,即在In条件复杂查询语句
6. 更新操作条件必须有索引,通过explain确认执行计划走索引,尽量使用pk主键
7. 查询条件必须走索引
8. 原则上不允许应用使用delete语句,如有需要,必须记log,经过团队评审
9. 实体类与数据库表对应,api接口下的实体与dao层不一致,dao层实体命名为XxxEntity,防止修改内部实体类影响接口稳定性。

6.3 数据库设计规范

    1. 禁止删除字段
    2. 禁止更新字段名称,类型,减少长度;可以修改增加字段长度或备注
    3. 数据库脚本支持提前上线,否则会影响热发布或者灰度发布
4. 每个领域实体表必须有一个领域主键驱动,便于信息查询
    5. 查询结果按需读取,防止因字段过大造成数据传输开销
    6. SQL命名准确,功能要单一,不能包含多种含义功能,维护会更复杂

6.4 redis缓存使用规范

1. 存放业务数据,必须设置ttl

6.5 内存缓存使用规范

1. 内存缓存只能存放开关类配置数据

7. main目录下的代码中不能包含以下代码,test目录下可以有

    1. public staitc void main(String[] args) 
    2. System.out.println();
    3. e.printStackTrace();

8. 输入输出流要再finally块中关闭

9. 定义变量用static final,而不是final static。

9.1 public static 必须加上final,防止被篡改
9.2 protected static 可以不用加上final

10. 泛型在定义变量时已经指定类型,实例化时不需要再指定泛型的类型。

//不建议的示例
Map<String, Object> map = new HashMap<String, Object>;
List<Map<String, Object>> resltList = new ArrayList<Map<String, Object>>();
//建议的示例
Map<String, Object> map = new HashMap<>;
List<Map<String, Object>> resltList = new ArrayList<>();

11. 不能直接catch throwable。因为throwable里包含OOM等异常,而此类异常是不需要捕获的。

12. 方法或者方法体,都不能直接抛出一个Exception,只能抛出一个自定义的Exception子类,例如SeriviceException

因为如果直接抛出Exception,调用该方法的调用者有可能无法识别异常是系统抛出的还是应用抛出的。

亚马逊服务开发6大原则

  1. 所有团队的程序模块都要以通过Service Interface 方式将其数据与功能开放出来。
  2. 团队间的程序模块的信息通信,都要通过这些接口。
  3. 除此之外没有其它的通信方式。其他形式一概不允许:不能使用直接链结程序、不能直接读取其他团队的数据库、不能使用共享内存模式、不能使用别人模块的后门等等,唯一允许的通信方式只能是能过调用 Service Interface。
  4. 任何技术都可以使用。比如:HTTP、Corba、Pubsub、自定义的网络协议等等,都可以,贝佐斯不管这些。
  5. 所有的Service Interface,毫无例外,都必须从骨子里到表面上设计成能对外界开放的。也就是说,团队必须做好规划与设计,以便未来把接口开放给全世界的程序员,没有任何例外。
  6. 不这样的做的人会被炒鱿鱼。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,001评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,647评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,612评论 18 399
  • 北京,好像是不怎么刮风的。总是铁面无私的一幅样子。我经过了在北京的第五个夏天,巧的很,不管每年发生什么事情,北京的...
    付茉莉阅读 474评论 4 2
  • 下班回来,打开手机,看到朋友圈爆炸了,大概的事件是这样的,顺丰小哥给一北京出租车司机90秒连打脸6次,原因是小...
    志輝阅读 454评论 0 0