阿里规范Java开发手册最新–嵩山版分享和解读

最近做项目时间太紧,现在赶紧补一波博客,今天看到java阿里规范又出新版啦,这里给大家分享下!
PDF分享:https://pan.baidu.com/s/14wCPUD5zxbP9Fv8aMW4QBA
提取码:251k

(链接失效可以在下方评论哦,有理解错误的地方还望指正)
最新嵩山版相对于之前泰山版的增加了一些新内容的同时也对做了一些修改,下面给大家分享一下

比如:
1增加了前后端规约,包含14t条内容(内容在下面做了分享哦!)
2增加了,一些约定方法命名和key和Value的命名,增加一些限制,对Body的一些限制,请求头和请求体的大小限制
3在传输的方式限制推荐json,不推荐使用xml的方式,主要是应该在解析和反解析的成本方面json比较小

1.比较浮点型和BigDecimalcompareTo和equals的区别

嵩山版增加了比较浮点型和BigDecimal的一些描述,增加了compareTo和equals的区别
比如:在比较浮点数用eq,当精度不同时,输出false,比如1.0和1.00 equals的结果应该为真,但因为1.0 是十分之一的精度而1.00是百分之一的精度,所以在equals在比较BigDecimal的时候回去比较值以及精度Scale,导致1.0和1.00在比较的时候预期是相等的但是实际上是不相等的,所以推荐使用compareTo,当compareTo的结果为0时,就说明时相等的,在处理资金有关的问题上会出现错误。
2.订单业务的编号问题,在前后端交互的时候推荐使用String类型
对于在前端和后端的传输上对于一些订单号传输的问题,推荐使用String类型
因为在实际开发中,后端long传给前端的double会产生订单编号丢失的问题,在科学计数法表示中,long的表示范围时2的63次方-1,在long表示范围之内去传给,大于2的53次方以后,最后的有效数字会被丢失,导致订单号被截断

而double的表示范围是double:
        1bit(符号位) 11bits(指数位) 52bits(尾数位)

所以后端long在前端用double来接时候,当使用指数位能精确表示的时候,是不会出问题的,但是在使用尾数位时,就会有一些有效数字被截断,推荐用String方式传输,超过2的53次方之后时一个概率问题,大概在long的16位,所以long类型大于16位的时候,一定要用String方式传输。

3.有关敏感信息的日志核心数据,需要保存六个月,这是国家规定

4.HashMap中对于1024个元素扩容的次数
HashMap中对于1024个元素扩容的次数,更改为resize的次数
在new一个HashMap,并不会分配空间,只有在第一次put的时候,会调一次resize,对于是否属于扩容的词有所争议,改为resize的次数,不叫扩容的次数
5.修改了架构分层中Manager层,调整了架构分层
Manager是通用的业务下层,Service层是解决业务逻辑的,和业务强相关的一些 逻辑。Manager和Service最大的区别就是Manager可以有多个Service服务,下层是通用的能力,并且还要封装对外的第三方接口,比如淘宝调支付宝接口,可能在Manager层中进行适配的转换,对于model这个逻辑单元,当把可重用的逻辑单元更加明确的存在Manager层中,Service可能会为多个Web层复用,但更多的是业务规则。

下面是有关前后端规约

(十) 前后端规约

  1. 【强制】前后端交互的API,需要明确协议、域名、路径、请求方法、请>求内容、状态码、响 应体。 说明:
    (1) 协议:生产环境必须使用 >HTTPS。
    (2) 路径:每一个 API 需对应一个路径,表示API 具体的请求地址:
    a代表一种资源,只能为名词,推荐使用复数,不能为动词,请求方法已经表达动作意义。
    b URL 路径不能使用大写,单词如果需要分隔,统一使用下划线。
    c 路径禁止携带表示请求内容类型的后缀,比如".json",".xml",通过 accept 头表达即可。
    (3) 请求方法:对具体操作的定义,常见的请求方法如下: a) GET:从服务器取出资源。 b) POST:在服务器新建一个资源。 c)
    PUT:在服务器更新资源。 d) DELETE:从服务器删除资源。 (4) 请求内容:URL
    带的参数必须无敏感信息或符合安全要求;body 里带参数时必须设置 Content-Type。 (5) 响应体:响应体 body
    可放置多种数据类型,由 Content-Type 头来确定。
  2. 【强制】前后端数据列表相关的接口返回,如果为空,则返回空数组[]或空集合{}。 说明:此条约定有利于数据层面上的协作更加高效,减少前端很多琐碎的 null 判断。
  3. 【强制】服务端发生错误时,返回给前端的响应信息必须包含 HTTP 状态码,errorCode、 errorMessage、用户提示信息四个部分。
    说明:四个部分的涉众对象分别是浏览器、前端开发、错误排查人员、用户。其中输出给用户的提示信息
    要求:简短清晰、提示友好,引导用户进行下一步操作或解释错误原因,提示信息可以包括错误原因、上 下文环境、推荐操作等。
    errorCode:参考附表 3。errorMessage:简要描述后端出错原因,便于错误排
    查人员快速定位问题,注意不要包含敏感数据信息。 正例:常见的HTTP 状态码如下 1) 200 OK:
    表明该请求被成功地完成,所请求的资源发送到客户端。 2) 401 Unauthorized:
    请求要求身份验证,常见对于需要登录而用户未登录的情况。 3) 403
    Forbidden:服务器拒绝请求,常见于机密信息或复制其它登录用户链接访问服务器的情况。 4) 404 Not Found:
    服务器无法取得所请求的网页,请求资源不存在。 5) 500 Internal Server Error: 服务器内部错误。
  4. 【强制】在前后端交互的 JSON格式数据中,所有的 key 必须为小写字母开始的 lowerCamelCase 风格,符合英文表达习惯,且表意完整。 正例:errorCode / errorMessage / assetStatus /
    menuList / orderList / configFlag 反例:ERRORCODE / ERROR_CODE /
    error_message / error-message / errormessage / ErrorMessage / msg
  5. 【强制】errorMessage 是前后端错误追踪机制的体现,可以在前端输出到 type=“hidden” 文字类控件中,或者用户端的日志中,帮助我们快速地定位出问题。
  6. 【强制】对于需要使用超大整数的场景,服务端一律使用 String 字符串类型返回,禁止使用 Long 类型。 说明:Java 服务端如果直接返回 Long 整型数据给前端,JS 会自动转换为Number 类型(注:此类型为双 精度浮点数,表示原理与取值范围等同于
    Java 中的 Double)。Long 类型能表示的最大值是 2 的63 次方 -1,在取值范围之内,超过 2 的 53 次方
    (9007199254740992)的数值转化为 JS 的Number 时,有些数 值会有精度损失。扩展说明,在 Long
    取值范围内,任何 2 的指数次整数都是绝对不会存在精度损失的,所
    以说精度损失是一个概率问题。若浮点数尾数位与指数位空间不限,则可以精确表示任何整数,但很不幸, 双精度浮点数的尾数位只有 52 位。
    反例:通常在订单号或交易号大于等于 16 位,大概率会出现前后端单据不一致的情况,比如,“orderId”:
    362909601374617692,前端拿到的值却是: 362909601374617660。
  7. 【强制】HTTP 请求通过URL 传递参数时,不能超过 2048 字节。 说明:不同浏览器对于 URL 的最大长度限制略有不同,并且对超出最大长度的处理逻辑也有差异,2048 字节是取所有浏览器的最小值
  8. 反例:某业务将退货的商品 id 列表放在URL 中作为参数传递,当一次退货商品数量过多时,URL 参数超长, 传递到后端的参数被截断,导致部分商品未能正确退货。
  9. 【强制】HTTP 请求通过 body 传递内容时,必须控制长度,超出最大长度后,后端解析会出 错。 说明:nginx 默认限制是 1MB,tomcat 默认限制为 2MB,当确实有业务需要传较大内容时,可以通过调 大服务器端的限制。
  10. 【强制】在翻页场景中,用户输入参数的小于 1,则前端返回第一页参数给后端;后端发现用 户输入的参数大于总页数,直接返回最后一页。
  11. 【强制】服务器内部重定向必须使用 forward;外部重定向地址必须使用URL 统一代理模块 生成,否则会因线上采用 HTTPS 协议而导致浏览器提示“不安全”,并且还会带来URL 维护 不一致的问题。
  12. 【推荐】服务器返回信息必须被标记是否可以缓存,如果缓存,客户端可能会重用之前的请求 结果。 说明:缓存有利于减少交互次数,减少交互的平均延迟。 正例:http 1.1 中,s-maxage
    告诉服务器进行缓存,时间单位为秒,用法如下, response.setHeader(“Cache-Control”,
    “s-maxage=” + cacheSeconds);
  13. 【推荐】服务端返回的数据,使用 JSON格式而非XML。 说明:尽管HTTP 支持使用不同的输出格式,例如纯文本,JSON,CSV,XML,RSS 甚至HTML。如果我 们使用的面向用户的服务,应该选择
    JSON作为通信中使用的标准数据交换格式,包括请求和响应。此外, application/JSON是一种通用的
    MIME类型,具有实用、精简、易读的特点。
  14. 【推荐】前后端的时间格式统一为"yyyy-MM-dd HH:mm:ss",统一为GMT。
  15. 【参考】在接口路径中不要加入版本号,版本控制在 HTTP 头信息中体现,有利于向前兼容。 说明:当用户在低版本与高版本之间反复切换工作时,会导致迁移复杂度升高,存在数据错乱风险。

工程结构

六、工程结构 (一) 应用分层 1. 【推荐】根据业务架构实践,结合业界分层规范与流行技术框架分析,推荐分层结构如图所示,
默认上层依赖于下层,箭头关系表示可直接依赖,如:开放 API 层可以依赖于Web层 (Controller 层),也可以直接依赖于
Service 层,依此类推:

java 阿里代码规范 阿里java开发规范pdf_正例


• 开放 API 层:可直接封装 Service 接口暴露成 RPC 接口;通过Web 封装成http 接口;网关控制层等。 •


终端显示层:各个端的模板渲染并执行显示的层。当前主要是 velocity 渲染,JS 渲染,JSP 渲染,移 动端展示等。 • Web


层:主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。 • Service 层:相对具体的业务逻辑服务层。 •


Manager 层:通用业务处理层,它有如下特征: 1) 对第三方平台封装的层,预处理返回结果及转化异常信息,适配上层接口。 2) 对


Service 层通用能力的下沉,如缓存方案、中间件通用处理。 3) 与 DAO层交互,对多个DAO的组合复用。 •


DAO层:数据访问层,与底层 MySQL、Oracle、Hbase、OB等进行数据交互。 • 第三方服务:包括其它部门 RPC


服务接口,基础平台,其它公司的 HTTP 接口,如淘宝开放平台、支 付宝付款服务、高德地图服务等。 •


外部数据接口:外部(应用)数据存储服务提供的接口,多见于数据迁移场景中。


2. 【参考】(分层异常处理规约)在 DAO层,产生的异常类型有很多,无法用细粒度的异常进 行 catch,使用 catch(Exception e)方式,并 throw new DAOException(e),不需要打印日志,因 为日志在


Manager/Service 层一定需要捕获并打印到日志文件中去,如果同台服务器再打日志,浪费性能和存储。在 Service 层出现异常时,必须记录出错日志到磁盘,尽可能带上参数信息, 相当于保护案发现场。Manager 层与 Service 同机部署,日志方式与 DAO层处理一致,如果是 单独部署,则采用与 Service 一致的处理方式。Web


层绝不应该继续往上抛异常,因为已经处 于顶层,如果意识到这个异常将导致页面无法正常渲染,那么就应该直接跳转到友好错误页面,


尽量加上友好的错误提示信息。开放接口层要将异常处理成错误码和错误信息方式返回。


3. 【参考】分层领域模型规约: • DO(Data Object):此对象与数据库表结构一一对应,通过 DAO层向上传输数据源对象。 • DTO(Data Transfer Object):数据传输对象,Service 或Manager 向外传输的对象。 •


BO(Business Object):业务对象,可以由 Service 层输出的封装业务逻辑的对象。 •


Query:数据查询对象,各层接收上层的查询请求。注意超过 2 个参数的查询封装,禁止使用 Map 类 来传输。 • VO(View


Object):显示层对象,通常是Web 向模板渲染引擎层传输的对象。

设计规约

七、设计规约

  1. 【强制】存储方案和底层数据结构的设计获得评审一致通过,并沉淀成为文档。 说明:有缺陷的底层数据结构容易导致系统风险上升,可扩展性下降,重构成本也会因历史数据迁移和系
    统平滑过渡而陡然增加,所以,存储方案和数据结构需要认真地进行设计和评审,生产环境提交执行后, 需要进行 double check。
    正例:评审内容包括存储介质选型、表结构设计能否满足技术方案、存取性能和存储空间能否满足业务发
    展、表或字段之间的辩证关系、字段名称、字段类型、索引等;数据结构变更(如在原有表中新增字段) 也需要进行评审通过后上线。
  2. 【强制】在需求分析阶段,如果与系统交互的User 超过一类并且相关的User Case 超过 5 个, 使用用例图来表达更加清晰的结构化需求。
  3. 【强制】如果某个业务对象的状态超过 3 个,使用状态图来表达并且明确状态变化的各个触发 条件。 说明:状态图的核心是对象状态,首先明确对象有多少种状态,然后明确两两状态之间是否存在直接转换 关系,再明确触发状态转换的条件是什么。
    正例:淘宝订单状态有已下单、待付款、已付款、待发货、已发货、已收货等。比如已下单与已收货这两 种状态之间是不可能有直接转换关系的。
  4. 【强制】如果系统中某个功能的调用链路上的涉及对象超过 3 个,使用时序图来表达并且明确 各调用环节的输入与输出。 说明:时序图反映了一系列对象间的交互与协作关系,清晰立体地反映系统的调用纵深链路。
  5. 【强制】如果系统中模型类超过 5 个,并且存在复杂的依赖关系,使用类图来表达并且明确类 之间的关系。 说明:类图像建筑领域的施工图,如果搭平房,可能不需要,但如果建造蚂蚁 Z 空间大楼,肯定需要详细 的施工图。
  6. 【强制】如果系统中超过 2 个对象之间存在协作关系,并且需要表示复杂的处理流程,使用活 动图来表示。 说明:活动图是流程图的扩展,增加了能够体现协作关系的对象泳道,支持表示并发等。
  7. 【推荐】系统架构设计时明确以下目标: ⚫ 确定系统边界。确定系统在技术层面上的做与不做。 ⚫ 确定系统内模块之间的关系。确定模块之间的依赖关系及模块的宏观输入与输出。 ⚫
    确定指导后续设计与演化的原则。使后续的子系统或模块设计在一个既定的框架内和技术方向上继 续演化。 ⚫
    确定非功能性需求。非功能性需求是指安全性、可用性、可扩展性等。
  8. 【推荐】需求分析与系统设计在考虑主干功能的同时,需要充分评估异常流程与业务边界。 反例:用户在淘宝付款过程中,银行扣款成功,发送给用户扣款成功短信,但是支付宝入款时由于断网演
    练产生异常,淘宝订单页面依然显示未付款,导致用户投诉。 9 【推荐】类在设计与实现时要符合单一原则。
    说明:单一原则最易理解却是最难实现的一条规则,随着系统演进,很多时候,忘记了类设计的初衷。
  9. 【推荐】谨慎使用继承的方式来进行扩展,优先使用聚合/组合的方式来实现。 说明:不得已使用继承的话,必须符合里氏代换原则,此原则说父类能够出现的地方子类一定能够出现,
    比如,“把钱交出来”,钱的子类美元、欧元、人民币等都可以出现。
  10. 【推荐】系统设计阶段,根据依赖倒置原则,尽量依赖抽象类与接口,有利于扩展与维护。 说明:低层次模块依赖于高层次模块的抽象,方便系统间的解耦。
  11. 【推荐】系统设计阶段,注意对扩展开放,对修改闭合。 说明:极端情况下,交付的代码是不可修改的,同一业务域内的需求变化,通过模块或类的扩展来实现。
  12. 【推荐】系统设计阶段,共性业务或公共行为抽取出来公共模块、公共配置、公共类、公共方 法等,在系统中不出现重复代码的情况,即 DRY 原则(Don’t Repeat Yourself)。
    说明:随着代码的重复次数不断增加,维护成本指数级上升。随意复制和粘贴代码,必然会导致代码的重复,
    在维护代码时,需要修改所有的副本,容易遗漏。必要时抽取共性方法,或者抽象公共类,甚至是组件化。 正例:一个类中有多个 public
    方法,都需要进行数行相同的参数校验操作,这个时候请抽取: private boolean checkParam(DTO dto) {…}
  13. 【推荐】避免如下误解:敏捷开发 = 讲故事 + 编码 + 发布。 说明:敏捷开发是快速交付迭代可用的系统,省略多余的设计方案,摒弃传统的审批流程,但核心关键点上 的必要设计和文档沉淀是需要的。
    反例:某团队为了业务快速发展,敏捷成了产品经理催进度的借口,系统中均是勉强能运行但像面条一样
    的代码,可维护性和可扩展性极差,一年之后,不得不进行大规模重构,得不偿失。
  14. 【参考】设计文档的作用是明确需求、理顺逻辑、后期维护,次要目的用于指导编码。 说明:避免为了设计而设计,系统设计文档有助于后期的系统维护和重构,所以设计结果需要进行分类归 档保存。
  15. 【参考】可扩展性的本质是找到系统的变化点,并隔离变化点。 说明:世间众多设计模式其实就是一种设计模式即隔离变化点的模式。 正例:极致扩展性的标志,就是需求的新增,不会在原有代码交付物上进行任何形式的修改。
  16. 【参考】设计的本质就是识别和表达系统难点。 说明:识别和表达完全是两回事,很多人错误地认为识别到系统难点在哪里,表达只是自然而然的事情,
    但是大家在设计评审中经常出现语焉不详,甚至是词不达意的情况。准确地表达系统难点需要具备如下能 力:
    表达规则和表达工具的熟练性。抽象思维和总结能力的局限性。基础知识体系的完备性。深入浅出的 生动表达力。
  17. 【参考】代码即文档的观点是错误的,清晰的代码只是文档的某个片断,而不是全部。 说明:代码的深度调用,模块层面上的依赖关系网,业务场景逻辑,非功能性需求等问题是需要相应的文 档来完整地呈现的。
  18. 【参考】在做无障碍产品设计时,需要考虑到: ⚫ 所有可交互的控件元素必须能被 tab 键聚焦,并且焦点顺序需符合自然操作逻辑。 ⚫ 用于登录校验和请求拦截的验证码均需提供图形验证以外的其它方式。 ⚫ 自定义的控件类型需明确交互方式。
    正例:用户登录场景中,输入框的按钮都需要考虑 tab键聚焦,符合自然逻辑的操作顺序如下,“输入用
    户名,输入密码,输入验证码,点击登录”,其中验证码实现语音验证方式。如果有自定义标签实现的控 件设置控件类型可使用 role 属性。