阿里开发手册重点总结
1. 编程规约
1. 1命名规约
- 【强制】类名使用 UpperCamelCase 风格,必须遵从驼峰形式,但以下情形例外:(领域模型的相关命名)DO / DTO / VO / DAO 等。
- 【强制】方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵从驼峰形式。
- 【强制】常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。
- 【强制】异常类命名使用 Exception结尾;测试类命名以它要测试的类的名称开始,以 Test结尾;抽象类命名使用 Abstract 或 Base 开头。
- 【强制】POJO 类中的任何布尔类型的变量,都不要加 is,否则部分框架解析会引起序列化错误。
- 【强制】包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。
- 【推荐】接口类中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁性,并加上有效的 javadoc 注释。
- 各层命名规约:
Service/DAO 层方法命名规约
a) 获取单个对象的方法用 get 做前缀。
b) 获取多个对象的方法用 list 做前缀。
c) 获取统计值的方法用 count 做前缀。
d) 插入的方法用 save(推荐)或 insert 做前缀。
e) 删除的方法用 remove(推荐)或 delete 做前缀。
f) 修改的方法用 update 做前缀。
Service/DAO 领域模型命名规约
a) 数据对象:xxxDO,xxx 即为数据表名。
b) 数据传输对象:xxxDTO,xxx 为业务领域相关的名称。
c) 展示对象:xxxVO,xxx 一般为网页名称。
d) POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO。
1. 2常量定义
- 【强制】不允许出现任何魔法值(即未经定义的常量)直接出现在代码中。
String key="Id#taobao_"+tradeId;
cache.put(key, value);
- 【强制】long 或者 Long 初始赋值时,必须使用大写的 L,不能是小写的 l,小写容易跟数字 1混淆,造成误解。
1. 3OOP规约【面向对象规约】
- 【强制】避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。
- 【强制】所有的覆写方法,必须加@Override 注解。
- 【强制】相同参数类型,相同业务含义,才可以使用 Java 的可变参数,避免使用 Object。
说明:可变参数必须放置在参数列表的最后。(★提倡同学们尽量不用可变参数编程★ 看源码的时候有时候会看到可变参数)
正例:public User getUsers(String type, Integer... ids);
- 【强制】Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。
- 【强制】关于基本数据类型与包装数据类型的使用标准如下:
1) 所有的 POJO 类属性必须使用包装数据类型。
2) RPC 方法的返回值和参数必须使用包装数据类型。
3) ★所有的局部变量推荐使用基本数据类型★。
- 【强制】POJO 类必须写 toString 方法。使用工具类 source> generate toString 时,如果继承了另一个 POJO 类,注意在前面加一下 super.toString。
- 【强制】在getter/setter 方法中,尽量不要增加业务逻辑,增加排查问题难度。
public Integer getData(){
if(true) {
return data + 100;
} else {
return data - 100;
}
}
- 【推荐】循环体内,字符串的联接方式,使用 StringBuilder 的 append 方法进行扩展。
1. 4集合处理
- 【强制】ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException 异常:java.util.RandomAccessSubList cannot be cast to java.util.ArrayList ;
说明:subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList ,而是 ArrayList
的一个视图,对于 SubList 子列表的所有操作最终会反映到原列表上。
- 【强制】使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一样的数组,大小就是 list.size()。
反例:直接使用 toArray 无参方法存在问题,此方法返回值只能是 Object[]类,若强转其它
类型数组将出现 ClassCastException 错误。
正例:
List<String> list = new ArrayList<String>(2);
list.add("guan");
list.add("bao");
String[] array = new String[list.size()];
array = list.toArray(array);
- 【强制】使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。
说明:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList
体现的是适配器模式,只是转换接口,后台的数据仍是数组。
String[] str = new String[] { "a", "b" };
List list = Arrays.asList(str);
第一种情况:list.add("c"); 运行时异常。
第二种情况:str[0]= "gujin"; 那么 list.get(0)也会随之修改。
- 【参考】利用 Set 元素唯一的特性,可以快速对另一个集合进行去重操作,避免使用 List 的 contains 方法进行遍历去重操作。
1. 5其他
- 【强制】避免用 Apache Beanutils 进行属性的 copy。
说明:Apache BeanUtils 性能较差,可以使用其他方案比如 Spring BeanUtils, CglibBeanCopier。
- 【强制】注意 Math.random() 这个方法返回是 double 类型,注意取值范围 0≤x<1(能够取到零值,注意除零异常),如果想获取整数类型的随机数,不要将 x 放大 10 的若干倍然后取整,直接使用 Random 对象的 nextInt 或者 nextLong 方法。
- 【强制】获取当前毫秒数:System.currentTimeMillis(); 而不是 new Date().getTime();
2. MYSQL规约
2. 1建表规约
- 【强制】表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint ( 1 表示是,0 表示否),此规则同样适用于 odps 建表。
说明:任何字段如果为非负数,必须是 unsigned。
- 【强制】表名不使用复数名词。
- 【强制】小数类型为 decimal,禁止使用 float 和 double。
说明:float 和 double 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不正确的结果。如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数分开存储。
- 【强制】如果存储的字符串长度几乎相等,使用 CHAR 定长字符串类型。
- 【强制】varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此值,定义字段类型为 TEXT,独立出来一张表,用主键来对应,避免影响其它字段索引效率。
- 【推荐】表的命名最好是加上“业务名称_表的作用”,避免上云梯后,再与其它业务表关联时有混淆。
正例:tiger_task / tiger_reader / mpp_config
- 【推荐】字段允许适当冗余,以提高性能,但是必须考虑数据同步的情况。
- 【参考】合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检索速度。
正例:
人的年龄用 unsigned tinyint(表示范围 0-255,人的寿命不会超过 255 岁);
海龟就必须是 smallint,但如果是太阳的年龄,就必须是 int;
如果是所有恒星的年龄都加起来,那么就必须使用 bigint。
##2. 2SQL规约 1.