读书笔记-阿里巴巴开发手册

读书笔记-阿里巴巴开发手册

前言

  • 本笔记针对最新版本-泰山版开发手册进行阐述分析

mark

mark

希望各位未来可以有所大成,达到(会当凌绝顶,一览众山小)的境界。

mark

废话不多说,我们直接来看正文….

1. 编码规约

1.1 命名风格

【强制】代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。

1
反例:_name / __name / $name / name_ / name$ / name__

尽管 $ 可以作为标识符使用,然而我们应该尽量避免对其使用。

  • 原因:$ 通常在编译器生成的标识符名称中使用,如果我们也使用这个符号,可能会有一些意想不到的错误发生….
  • 意向不到的错误示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package test;

public class User$VIP {
public static void main(String[] args) {
User user = new User();
User.VIP vip = user.new VIP();
vip.print();
}
}

class User{
class VIP{
void print(){
System.out.println("成员类");
}
}
}

仔细阅读以下,似乎并没有什么问题,代码也比较简单,但正在我们编译的时候,IDEA提示我们:

mark

定义了重复的代码?归根到底,都是 $ 惹的祸!因为 $ 被编译器所使用,在源文件(.java文件)编译成字节码(.class文件)中,会被称为顶层类型与嵌套类型之间的连接符。

例如:如果存在一个顶层类A,在其内声明一个成员类B,那么编译之后就会产生两个class文件,分别是A.classA$B.class

就本程序来说,会生成 3 个 class 文件(如果可以编译的话),分别是 User$VIP.class(顶层类)、User.classUser$VIP.class(User 类的成员类,也就是类 VIP)。由于试图存在两个 User$VIP.class 所以才会报错!

  • 编程相关的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式
1
2
正例:ali / alibaba / taobao / cainiao/ aliyun/ youku / hangzhou 等国际通用的名称,可视同英文。
反例:DaZhePromotion [打折] / getPingfenByName() [评分] / int 某变量 = 3
  • 类名要使用UpperCamelCase风格(大驼峰命名)
1
2
正例:ForceCode / UserDO / HtmlDTO / XmlService / TcpUdpDeal / TaPromotion
反例:forcecode / UserDo / HTMLDto / XMLService / TCPUDPDeal / TAPromotion
  • 方法名,参数名,成员变量,局部变量统一使用lowerCamelCase(小驼峰命名)
1
正例: localValue / getHttpMessage() / inputUserId
  • 常量名全部大写,单词间用下划线隔开。
1
2
正例:MAX_STOCK_COUNT / CACHE_EXPIRED_TIME
反例:MAX_COUNT / EXPIRED_TIME
  • 抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类

    命名以它要测试的类的名称开始,以 Test 结尾。

  • 类型中括号紧挨相邻来表示数组数组 int[] arrayDemo;

1
2
正例:定义整形数组 int[] arrayDemo;
反例:在 main 参数中,使用 String args[]来定义。
  • POJO 类中的任何布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列

    化错误。

    1
    定义为基本数据类型 boolean isSuccess;的属性,它的方法也是 isSuccess() ,RPC框架在反向解析的时候,“以为”对应的属性名称是 success ,导致属性获取不到,进而抛出异常。
  • 包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。
  • 包名统一使用单数形式,但是如果类名有复数的含义,类名也可以使用负数形式。
1
2
包名:util
类名:RedisUtils
  • 避免在子父类成员变量之间,或者不同代码块的局部变量之间采用完全相同的命名,使可读性降低。
1
2
3
说明:子类、父类成员变量名相同,即使是 public 类型的变量也是能够通过编译,而局部变量在同一方法
内的不同代码块中同名也是合法的,但是要避免使用。对于非 setter/getter 的参数名称也要避免与成员变
量名称相同。

mark

  • 为了达到代码自解释的目标,任何自定义编程元素在命名时,使用尽量完整的单词组

    合来表达。

1
2
正例:在 JDK 中,对某个对象引用的 volatile 字段进行原子更新的类名为:AtomicReferenceFieldUpdater。
反例:常见的方法内变量为 int a;的定义方式。
  • 在常量变量命名的时候,表示类型的名词放在词尾,来提高辨识度
1
2
正例:startTime / workQueue / nameList / TERMINATED_THREAD_COUNT
反例:startedAt / QueueOfWork / listName / COUNT_TERMINATED_THREAD
  • 如果模块、接口、类、方法使用了设计模式,在命名时需体现出具体模式。
1
2
3
4
说明:将设计模式体现在名字中,有利于阅读者快速理解架构设计理念。
正例: public class OrderFactory;
public class LoginProxy;
public class ResourceObserver;
  • 接口类中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的间接性,并加上有效的Javadoc注释。 (尽量不要在接口中定义变量,如果一定要定义变量,确定与接口方法相关,并且是整个应用的基础常量。)
1
2
3
4
5
正例:接口方法签名 void commit();
接口基础常量 String COMPANY = "alibaba";

反例:接口方法定义 public abstract void f();
说明:JDK8 中接口允许有默认实现,那么这个 default 方法,是对所有实现类都有价值的默认实现。
  • 接口和实现类的两套规则
  1. 对于Service和DAO类,基于SOA理念,暴露出来的一定是接口,内部的实现类用Impl的后缀与接口相区别
1
正例:CacheServiceImpl 实现 CacheService 接口。
  1. 如果是形容能力的接口名称,取对应的形容词为接口名(通常是–able 的形容词)。
1
正例:AbstractTranslator 实现 Translatable 接口。
  • 枚举类带上Enum后缀,枚举成员名称需要全部大写,单词用下换线隔开
1
2
说明:枚举是特殊的常量类,且构造方法被默认强制私有。
正例:枚举名字是ProcessStatusEnum的成员名称:SUCCESS/UNKNOWN_REASON
  • 各层命名规约:
    • Service/DAO 层方法命名规约
      • 获取单个对象的方法用get做前缀
      • 获取多个对象的方法用list做前缀,复数结尾 如listObjects
      • 获取统计值的方法用count做前缀
      • 插入的方法用save/insert做前缀
      • 删除的方法用remove/delete做前缀
      • 修改的方法用update做前缀
    • 领域模型命名规约
      • 数据对象:xxxDO, 其中xxx是数据表名
      • 数据传输对象: xxxDTO ,xxx 为业务领域相关的名称。
      • 展示对象:xxxVO, 其中xxx一般是网页的名字
      • POJO是DO/DTO/BO/VO的统称,禁止命名成xxxPOJO

1.2 常量定义

  • 不允许任何魔法值(即未经预先定义的常量)直接出现在代码中。
1
2
3
4
反例:
//本例中同学 A 定义了缓存的 key,然后缓存提取的同学 B 使用了 Id#taobao 来提取,少了下划线,导致故障。
String key = "Id#taobao_" + tradeId;
cache.put(key, value);
  • 在long或者Long赋值时候,数值使用大写的L,不能是小写的l,小写容易跟数字搞混
1
说明:Long a = 2l; 写的是数字的 21,还是 Long 型的 2。
  • 不要使用一个常量类维护所有的常量,要按常量功能进行分类,分开维护
1
2
说明:大而全的常量类,杂乱无章,不利于理解和维护
正例:缓存相关的放到CacheConsts下,系统配置的放到ConfigConsts下
  • 常量的复用层次有五层
    • 跨应用共享常量
    • 应用内共享常量
    • 子工程内共享常量
    • 包内共享常量
    • 类内共享常量
1
2
3
类内共享常量:private static final 来定义
包内共享常量: 即当前包下单独constant目录下
子工程内部共享常量: 子工程constant目录下
  • 如果一个变量值仅在一个固定范围内变化用enum类型来定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 说明:如果存在名称之外的延伸类型应使用enum类型,下面正例中的数字就是延伸信息,表示一年中的第几个季节

public enum SeasonEnum{
SPRING(1),SUMMER(2),AUTUMN(3),WINTER(4);

private int seq;

SeasonEnum(int seq){
this.seq = seq;
}

public int getSeq(){
return seq;
}
}

1.3 代码格式

  • 如果是大括号内为空,则简洁地写成{}即可,大括号中间无需换行和空格;如果是非

    空代码块则:

    1) 左大括号前不换行。

    2) 左大括号后换行。

    3) 右大括号前换行。

    4) 右大括号后还有 else 等代码则不换行;表示终止的右大括号后必须换行。

  • 左小括号和右边相邻字符之间不出现空格;右小括号和左边相邻字符之间也不出现空

    格;而左大括号前需要加空格。

    1
    反例:if (空格 a == b 空格)
  • if/for/while/switch/do 等保留字与括号之间都必须加空格
  • 任何二目、三目运算符的左右两边都需要加一个空格。
  • 采用4个空格的缩进,禁止使用tab字符

mark

  • 注释的双斜线与注释内容只有一个空格。
打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 Zhuuu
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信