阿里巴巴Java开发规范学习——编程规约(1)

2024-04-10 20:36

本文主要是介绍阿里巴巴Java开发规范学习——编程规约(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

阿里巴巴Java开发规范

一、编程规约

(一) 命名风格

1.【强制】类名使用UpperCamelCase 风格,但以下情形例外:DO / BO / DTO / VO / AO /

PO / UID 等。
正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion
反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion

  1. DO (Data Object):用于表示领域模型中的数据对象,通常包含业务相关的属性和行为。例如,CustomerDO, ProductDO
  2. BO (Business Object):用于封装业务逻辑和规则的类,可能包含对多个DO的操作。例如,OrderBO, InvoiceBO
  3. DTO (Data Transfer Object):主要用于在不同层(如表现层与业务层、服务层之间)传递数据的简单对象,只包含数据成员及简单的getter/setter方法。例如,UserDTO, AddressDTO
  4. VO (Value Object):在领域驱动设计(DDD)中,用于表示一个不变的、具有语义概念的对象,其属性值共同定义了对象的完整状态,如 ColorVO, MoneyVO
  5. AO (Application Object):在某些架构中,用于表示应用程序层的实体,负责协调业务逻辑和数据访问。例如,UserAO, RoleAO
  6. PO (Plain Old Object):通常指那些没有继承任何特殊框架或库提供的基类、未实现特定接口、未被注解标记、不含有任何门面方法(如getter/setter以外的方法)的简单对象。例如,CustomerPO, ItemPO
  7. UID (Unique Identifier):用于表示唯一标识符的类或接口,如全局唯一ID生成器 UUIDGenerator 或特定类型ID的类 UserId, OrderId
2. 【强制】常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。

正例:MAX_FILE_SIZE
反例:maxFileSize

3. 【强制】抽象类命名使用 Abstract 或Base 开头;异常类命名使用 Exception 结尾;测试类命名以它要测试的类的名称开始,以 Test 结尾。
  1. 抽象类命名使用 AbstractBase 开头
    这个规则建议在命名抽象类时,以 AbstractBase 作为前缀,以明确表示此类是一个抽象类,即不能被实例化,主要用于定义通用行为和接口,供子类继承实现。这样命名有助于开发者一眼识别出这是一个抽象类,了解其设计意图和用途。例如:AbstractAnimalBaseUserService

  2. 异常类命名使用 Exception 结尾
    异常类通常用于表示程序运行过程中遇到的错误情况。遵循这一规则,将 Exception 作为后缀添加到异常类名中,可以清晰地标识出此类是一个异常类,便于理解和管理程序中的错误处理逻辑。例如:InvalidInputExceptionResourceNotFoundException

抽象类中,可以以 Abstract 结尾吗?

虽然在技术层面上,以 Abstract 结尾命名抽象类并不违反任何编程语言的语法规定,但在实践中,以 AbstractBase 作为前缀已经是一种广泛接受且易于理解的抽象类命名约定。将 Abstract 放在类名末尾可能会导致以下问题:

  • 可读性降低:阅读代码时,开发人员习惯于从左到右扫描类名,将表示类性质的关键字放在开头有助于快速识别。将 Abstract 放在末尾可能需要额外的时间和注意力去判断类的性质。
  • 一致性受损:大部分编程社区和项目倾向于遵循将 AbstractBase 放在抽象类名开头的约定。若您的项目中出现以 Abstract 结尾的抽象类,可能会与团队内的其他代码或业界普遍做法产生不一致,增加理解成本。

综上所述,尽管没有严格禁止以 Abstract 结尾命名抽象类,但从可读性、一致性以及遵循最佳实践的角度考虑,建议遵循将 AbstractBase 放在抽象类名开头的命名规则。

4. 【强制】 POJO 类中布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列化错误。

反例:定义为基本数据类型 Boolean isDeleted 的属性,它的方法也是 isDeleted(),RPC框架在反向解析的时候,“误以为”对应的属性名称是 deleted,导致属性获取不到,进而抛出异常。

正例: 避免使用 is 前缀命名布尔类型的变量
直接使用描述状态的词汇作为变量名,如 deletedenabledvisible 等。相应的 getter 方法可以保持 JavaBean 规范,即对于布尔类型使用 is 前缀(如 isDeleted()),但对于属性名本身,则不带 is

问题背景:

在 Java 中,布尔类型的变量通常用来表示某种状态或属性的真假值。按照习惯,对于表示“是否具有某特性”的布尔变量,有时会采用 is 前缀来命名,如 isDeletedisEnabledisVisible 等。这种命名方式符合自然语言习惯,能够直观地传达变量的意义。

然而,在涉及序列化和反序列化的场景中,特别是与某些框架(如 RPC 框架、ORM 框架等)交互时,这种命名可能会导致问题。这是因为部分框架在自动处理对象的序列化和反序列化时,依赖于特定的命名约定来正确映射对象属性到外部格式(如 JSON、XML 或数据库字段)。

问题原因:

  1. JavaBean 规范与框架预期的差异
    JavaBean 规范规定,布尔类型的 getter 方法可以使用 is 前缀(如 isDeleted()),而其他类型的属性则使用 get 前缀(如 getName())。当框架尝试根据 getter 方法名反推属性名(去掉 isget 并将首字母小写)时,如果遇到以 is 开头的方法,可能会误以为对应的属性名为 deleted 而不是 isDeleted。这会导致框架在反序列化时找不到实际存在的 isDeleted 属性,从而引发错误。

  2. 外部格式映射规则
    在某些框架中,可能直接基于属性名进行序列化或反序列化。如果外部格式(如 JSON)要求属性名遵循特定的命名约定(如全小写、下划线分隔等),那么带有 is 缀的属性名在转换时可能会与预期不符,导致映射失败或错误。

5. 【强制】包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。

正例:应用工具类包名为 com.alibaba.ai.util、类名为MessageUtils (此规则参考spring
的框架结构)

6. 【推荐】如果模块、接口、类、方法使用了设计模式,在命名时需体现出具体模式。

说明:将设计模式体现在名字中,有利于阅读者快速理解架构设计理念。
正例:

  • public class OrderFactory;
  • public class LoginProxy;
  • public class ResourceObserver;
7. 【推荐】接口类中的方法和属性不要加任何修饰符号(public 也不要加)

保持代码的简洁性,并加上有效的Javadoc 注释。尽量不要在接口里定义变量,如果一定要定义变量,肯定是与接口方法相关,并且是整个应用的基础常量。
正例:

  • 接口方法签名 void commit();
  • 接口基础常量 String COMPANY = “alibaba”;
8. 接口和实现类命名的两套规则:

1)【强制】对于 Service 和DAO 类,基于 SOA 的理念,暴露出来的服务一定是接口,内部
的实现类用Impl 的后缀与接口区别。
正例:CacheServiceImpl 实现CacheService 接口。
2) 【推荐】 如果是形容能力的接口名称,取对应的形容词为接口名 (通常是–able 的形式)。
正例:AbstractTranslator 实现 Translatable 接口。

9. 【参考】枚举类名建议带上 Enum 后缀,枚举成员名称需要全大写,单词间用下划线隔开。

说明:枚举其实就是特殊的类,域成员均为常量,且构造方法被默认强制是私有。
正例:枚举名字为ProcessStatusEnum 的成员名称:SUCCESS / UNKNOWN_REASON。

10 .【参考】各层命名规约:

A) Service/DAO 层方法命名规约

1) 获取单个对象的方法用 get 做前缀。
2) 获取多个对象的方法用 list 做前缀,复数形式结尾如:listObjects。
3) 获取统计值的方法用 count 做前缀。
4) 插入的方法用save/insert 做前缀。
5) 删除的方法用remove/delete 做前缀。
6) 修改的方法用update 做前缀。
B) 领域模型命名规约
1) 数据对象:xxxDO,xxx 即为数据表名。
2) 数据传输对象:xxxDTO,xxx 为业务领域相关的名称。
3) 展示对象:xxxVO,xxx 一般为网页名称。
4) POJO 是DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。

(二) 常量定义

1. 【强制】不允许任何魔法值(即未经预先定义的常量)直接出现在代码中。

反例:

String key ="Id#taobao_" + tradeId;
cache.put(key, value);
2. 【强制】在long 或者Long 赋值时,数值后使用大写的L,不能是小写的 l,小写容易跟数字1 混淆,造成误解。

说明:Long a = 2l; 写的是数字的21,还是 Long 型的2?

3. 【推荐】不要使用一个常量类维护所有常量,要按常量功能进行归类,分开维护。

说明: 大而全的常量类, 杂乱无章, 使用查找功能才能定位到修改的常量,不利于理解和维护。
正例:缓存相关常量放在类 CacheConsts 下;系统配置相关常量放在类 ConfigConsts 下

4. 【推荐】常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量。

1) 跨应用共享常量:放置在二方库中,通常是 client.jar 中的constant 目录下。
2) 应用内共享常量:放置在一方库中,通常是子模块中的constant 目录下。
反例:易懂变量也要统一定义成应用内共享常量,两位攻城师在两个类中分别定义了表示“是”的变量:
类A 中:public static final String YES = “yes”
类B 中:public static final String YES = “y”;
A.YES.equals(B.YES),预期是true,但实际返回为false,导致线上问题。
3) 子工程内部共享常量:即在当前子工程的 constant 目录下。
4) 包内共享常量:即在当前包下单独的 constant 目录下。
5) 类内共享常量:直接在类内部 private static final 定义。

5. 【推荐】如果变量值仅在一个固定范围内变化用 enum 类型来定义。

枚举(Enum)类型的概念与特性:

enum(枚举)是一种特殊的类型,它允许定义一组命名的常量,这些常量通常是相互独立且互斥的。枚举类型在很多编程语言中都有支持,如 Java、C#、Python(通过枚举模块实现)等。枚举类型的优点包括:

  • 类型安全:枚举类型的变量只能被赋予其定义范围内预设的值,不允许赋值为其他未定义的值,增强了代码的健壮性和安全性。
  • 可读性强:枚举成员以具名常量的形式存在,使用有意义的名称代替原始值(如整数或字符串),提高了代码的可读性和自文档化能力。
  • 易于维护:当枚举成员有所增减或值发生变化时,只需修改枚举定义一处,所有引用该枚举的地方都会自动更新,降低了维护成本。

何时使用枚举来定义变量值范围:

当变量的取值仅在一个固定的、有限的范围内变化,并且这些值具有特定的语义时,非常适合使用枚举类型来定义。以下是一些典型的应用场景:

  1. 状态标识
    例如,订单的状态可能只有几个固定选项:PENDING(待处理)、PROCESSING(处理中)、COMPLETED(已完成)、CANCELLED(已取消)等。使用枚举可以清晰地表示这些状态,并确保状态值不会被错误地设置为无效值。
public enum OrderStatus {PENDING,PROCESSING,COMPLETED,CANCELLED
}
  1. 星期、月份等预定义集合
    例如,表示一周中的星期或一年中的月份,这类值都是固定的且具有明确语义。使用枚举可以使代码更具可读性,并防止拼写错误或使用非法值。
public enum DayOfWeek {MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY
}public enum Month {JANUARY,FEBRUARY,MARCH,APRIL,MAY,JUNE,JULY,AUGUST,SEPTEMBER,OCTOBER,NOVEMBER,DECEMBER
}
  1. 方向、颜色、角色类型等具有固定选项的分类
    例如,表示二维平面上的方向(NORTH, SOUTH, EAST, WEST),用户角色类型(ADMIN, MODERATOR, USER),或者颜色(RED, GREEN, BLUE 等)。这些情况都可以使用枚举来限制变量的取值范围。
public enum Direction {NORTH,SOUTH,EAST,WEST
}public enum UserRole {ADMIN,MODERATOR,USER
}public enum Color {RED,GREEN,BLUE,// ...
}

总结来说,当变量的取值范围固定且具有明确语义时,使用枚举类型来定义不仅可以提高代码的可读性和安全性,还能简化维护工作。遵循“如果变量值仅在一个固定范围内变化,用 enum 类型来定义”这一规范,有助于提升代码质量,符合良好的编程实践。

这篇关于阿里巴巴Java开发规范学习——编程规约(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/892080

相关文章

Java中Arrays类和Collections类常用方法示例详解

《Java中Arrays类和Collections类常用方法示例详解》本文总结了Java中Arrays和Collections类的常用方法,涵盖数组填充、排序、搜索、复制、列表转换等操作,帮助开发者高... 目录Arrays.fill()相关用法Arrays.toString()Arrays.sort()A

Spring Boot Maven 插件如何构建可执行 JAR 的核心配置

《SpringBootMaven插件如何构建可执行JAR的核心配置》SpringBoot核心Maven插件,用于生成可执行JAR/WAR,内置服务器简化部署,支持热部署、多环境配置及依赖管理... 目录前言一、插件的核心功能与目标1.1 插件的定位1.2 插件的 Goals(目标)1.3 插件定位1.4 核

如何使用Lombok进行spring 注入

《如何使用Lombok进行spring注入》本文介绍如何用Lombok简化Spring注入,推荐优先使用setter注入,通过注解自动生成getter/setter及构造器,减少冗余代码,提升开发效... Lombok为了开发环境简化代码,好处不用多说。spring 注入方式为2种,构造器注入和setter

基于Python开发一个图像水印批量添加工具

《基于Python开发一个图像水印批量添加工具》在当今数字化内容爆炸式增长的时代,图像版权保护已成为创作者和企业的核心需求,本方案将详细介绍一个基于PythonPIL库的工业级图像水印解决方案,有需要... 目录一、系统架构设计1.1 整体处理流程1.2 类结构设计(扩展版本)二、核心算法深入解析2.1 自

使用zip4j实现Java中的ZIP文件加密压缩的操作方法

《使用zip4j实现Java中的ZIP文件加密压缩的操作方法》本文介绍如何通过Maven集成zip4j1.3.2库创建带密码保护的ZIP文件,涵盖依赖配置、代码示例及加密原理,确保数据安全性,感兴趣的... 目录1. zip4j库介绍和版本1.1 zip4j库概述1.2 zip4j的版本演变1.3 zip4

Java堆转储文件之1.6G大文件处理完整指南

《Java堆转储文件之1.6G大文件处理完整指南》堆转储文件是优化、分析内存消耗的重要工具,:本文主要介绍Java堆转储文件之1.6G大文件处理的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言文件为什么这么大?如何处理这个文件?分析文件内容(推荐)删除文件(如果不需要)查看错误来源如何避

SpringBoot整合Dubbo+ZK注册失败的坑及解决

《SpringBoot整合Dubbo+ZK注册失败的坑及解决》使用Dubbo框架时,需在公共pom添加依赖,启动类加@EnableDubbo,实现类用@DubboService替代@Service,配... 目录1.先看下公共的pom(maven创建的pom工程)2.启动类上加@EnableDubbo3.实

SpringBoot整合(ES)ElasticSearch7.8实践

《SpringBoot整合(ES)ElasticSearch7.8实践》本文详细介绍了SpringBoot整合ElasticSearch7.8的教程,涵盖依赖添加、客户端初始化、索引创建与获取、批量插... 目录SpringBoot整合ElasticSearch7.8添加依赖初始化创建SpringBoot项

JAVA覆盖和重写的区别及说明

《JAVA覆盖和重写的区别及说明》非静态方法的覆盖即重写,具有多态性;静态方法无法被覆盖,但可被重写(仅通过类名调用),二者区别在于绑定时机与引用类型关联性... 目录Java覆盖和重写的区别经常听到两种话认真读完上面两份代码JAVA覆盖和重写的区别经常听到两种话1.覆盖=重写。2.静态方法可andro

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种