Skip to main content

代码规范

不以规矩,不能成方圆,好的代码风格在提高团队的开发效率,降低沟通成本,降低协作成本方面具有难以估量的作用,所以好的、可执行的代码规范对于团队开发来讲意义重大。

代码规范原则如下:
命名:见名知意。
结构:易于理解,可读性第一。


Java代码编码规范#

八条基本规范#

  1. 【强制】可读性第一原则。书写代码时,代码的可读性大于代码的简洁性。
    可读性第一,不要盲目追求代码的简洁,在团队协作中可读性好的代码才有更好的可维护性,而且一般情况下也具有更好的健壮性。代码的语法运用与书写顺序应以可读性优先。

  2. 【强制】逻辑复杂、难以理解的代码必须加入注释,比如:复杂的业务逻辑、算法、控制流程等。注释的内容需要写清楚代码的功能,如果有必要还要写明为什么这么做,以便于后续维护。

  3. 【强制】代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。
    说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。注意,即使纯拼音命名方式 也要避免采用。

    >正例:beijing / hangzhou 等国际通用的名称,可视同英文。
    >反例:DaZhePromotion [打折] / getPingfenByName() [评分] / int 某变量 = 3
  4. 类、方法、参数、变量的命名
    【强制】类名、方法名、变量名的命名要做到望文知意,为了达到代码自解释的目标,任何自定义编程元素在命名时,使完整的单词组合来表达其意,不要害怕名字过长。类名需要用名词表述、方法名需要按照功能进行表述、变量名需要按照实际用途进行表述。

    >正例:int orderCount;
    >反例:int a; // 随意命名方式,不可取。
    【强制】类名使用 UpperCamelCase 风格,必须遵从驼峰形式
    > 正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion
    > 反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion
    【强制】方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵从 驼峰形式。
    > 正例: localValue / getHttpMessage() / inputUserId
    【强制】变量命名遵循以下规则:
    - 非公共且非静态字段的名称以 `m` 开头。
    - 静态字段的名称以 `s` 开头。
    - 其他字段以小写字母开头。
    - 公共静态 `final` 字段(常量)采用全部大写单词间用下划线隔开的形式。
    - 力求语义表达完整清楚,不要嫌名字长。
    例:
    ```java
    public class MyClass {
    public static final int SOME_CONSTANT = 42;
    public int publicField;
    private static MyClass sSingleton;
    int mPackagePrivate;
    private int mPrivate;
    protected int mProtected;
    }
    ```
  1. 【强制】包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。
    例:应用工具类包名为 com.open.util、类名为 MessageUtils

  2. 【强制】单行字符数限制不超过 120 个,超出需要换行,换行时遵循如下原则:

    • 第二行相对第一行缩进 4 个空格,从第三行开始,不再继续缩进,参考示例。
    • 运算符与下文一起换行。
    • 方法调用的点符号与下文一起换行。
    • 方法调用时,多个参数,需要换行时,在逗号后进行。
    • 在括号前不要换行,见反例。

      正例

    StringBuffer sb = new StringBuffer();
    // 超过 120 个字符的情况下,换行缩进 4 个空格,点号和方法名称一起换行
    sb.append("zi").append("xin")...
    .append("huang")...
    .append("huang")...
    .append("huang");

    反例

    StringBuffer sb = new StringBuffer();
    // 超过 120 个字符的情况下,不要在括号前换行
    sb.append("zi").append("xin")...append
    ("huang");
    // 参数很多的方法调用可能超过 120 个字符,不要在逗号前换行
    method(args1, args2, args3, ...
    , argsX);
  3. 【强制】在 if/else/for/while/do 语句中必须使用大括号。即使只有一行代码,避免采用单行的编码方式:

    正例:if (condition) { statements; }
    反例:if (condition) statements;

  4. 【推荐】编写简短方法
    尽可能编写短小精炼的方法,如果某个方法代码超出40行,请考虑是否可以在不破坏程序结构的前提下对其进行拆解。

    > 有些情况下适宜编写较长的方法,因此这里对方法的代码长度没有做出硬性限制。但是在编写代码时过长的方法是典型的坏味道,一般情况下都需要使用重构的方式来祛除。

参考资料:
《阿里巴巴Java开发手册》
面向贡献者的 AOSP Java 代码样式指南


Kotlin代码编码规范#

Kotlin的编码规范的指导思想与Java编码规范类似,都是以代码规范的原则为指导思想:

命名:见名知意。
结构:易于理解,可读性第一。

所以在Java中的八条基本规范中所述的内容也基本适用于本部分,所以本部分的内容以 Kotlin 中的相较于 Java 的差异化内容为主,与Java部分相同的内容则不再赘述。

  1. 可读性第一原则。
    参照 Java 八条基本规范第 1 条。

  2. 逻辑复杂、难以理解的代码必须加入注释。
    参照 Java 八条基本规范第 2 条。

  3. 代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。
    参照 Java 八条基本规范第 3 条。

  4. 类、方法、参数、变量的命名
    【强制】类名、方法名、变量名的命名要做到望文知意,为了达到代码自解释的目标,任何自定义编程元素在命名时,使完整的单词组合来表达其意,不要害怕名字过长。类名需要用名词表述、方法名需要按照功能进行表述、变量名需要按照实际用途进行表述。

    >正例:var orderCount;
    >反例:var a; // 随意命名方式,不可取。
    【强制】类名使用 UpperCamelCase 风格,必须遵从驼峰形式
    > 正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion
    > 反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion
    【强制】方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵从驼峰形式。
    > 正例: localValue / getHttpMessage() / inputUserId
    【强制】幕后属性的名称(backing properties)

    如果一个类有两个概念上相同的属性,一个是公共 API 的一部分,另一个是实现细节,那么使用下划线作为私有属性名称的前缀:

    ```kotlin
    class C {
    private val _elementList = mutableListOf<Element>()
    val elementList: List<Element>
    get() = _elementList
    }
    ```
  1. 包名、文件命名
  • 包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。
  • 文件名遵循大驼峰命名法(单词直接连接,每个单词首字母大写)。
  • 如果文件中只包含一个单独的类,其名称应与所包含的类名相同(如:User.kt)。
  • 如果文件中包含多个类,或者只有一些顶级变量或方法声明,则文件名称要能够反映文件中所包含的内容(如:ProcessDeclarations.kt)。
  1. 格式化
  • 类头格式化

    1. 具有少数主构造函数参数的类可以写成一行:

      class Person(id: Int, name: String)
    2. 具有较长类头的类应该格式化,以使每个主构造函数参数都在带有缩进的独立的行中。 另外,右括号应该位于一个新行上。如果使用了继承,那么超类的构造函数调用或者所实现接口的列表应该与右括号位于同一行:

      class Person(
      id: Int,
      name: String,
      surname: String
      ) : Human(id, name) { /*……*/ }
    3. 对于多个接口,应该将超类构造函数调用放在首位,然后将每个接口应放在不同的行中:

      class Person(
      id: Int,
      name: String,
      surname: String
      ) : Human(id, name),
      KotlinMaker { /*……*/ }
  • 函数格式化

    1. 如果函数签名不适合单行,请使用以下语法:

      fun longMethodName(
      argument: ArgumentType = defaultValue,
      argument2: AnotherArgumentType
      ): ReturnType {
      // 函数体
      }

      函数参数使用常规缩进(4个空格)。

    2. 对于由单个表达式构成的函数体,优先使用表达式形式。

      fun foo(): Int { // 不良
      return 1
      }
      fun foo() = 1 // 良好
  • 控制流语句格式化

    1. 如果 if 或 when 语句的条件有多行,那么在语句体外边总是使用大括号。 将该条件的每个后续行相对于条件语句起始处缩进 4 个空格。 将该条件的右圆括号与左花括号放在单独一行:
      if (!component.isSyncing &&
      !hasAnyKotlinRuntimeInScope(module)
      ) {
      return createKotlinNotConfiguredPanel(module)
      }
  • Lambda 表达式格式化

    1. 在 lambda 表达式中,应该在花括号左右以及分隔参数与代码体的箭头左右留空格。 如果一个调用接受单个 lambda 表达式,应该尽可能将其放在圆括号外边传入。

      list.filter { it > 10 }
    2. 如果为 lambda 表达式分配一个标签,那么不要在该标签与左花括号之间留空格:

      fun foo() {
      ints.forEach lit@{
      // ……
      }
      }
    3. 在多行的 lambda 表达式中声明参数名时,将参数名放在第一行,后跟箭头与换行符:

      appendCommaSeparated(properties) { prop ->
      val propertyValue = prop.get(obj) // ……
      }
    4. 如果参数列表太长而无法放在一行上,请将箭头放在单独一行:

      foo {
      context: Context,
      environment: Env
      ->
      context.configureEnv(environment)
      }
  1. 编写简短方法
    参照 Java 八条基本规范第 8 条。

参考资料:
Kotlin Coding Conventions
Code Style Migration Guide


xml布局文件编码规范#

命名规范#

id 命名规范#

控件缩写_业务规则
例:et_user_namebtn_confirmbtn_reload

控件缩写#

为了方便控件 id 的命名,我们约定一些常用控件的缩写,控件缩写采用控件类名驼峰标识的首字母组合。
常用控件缩写:

控件名称缩写名称
TextViewtv
EditTextet
Buttonbtn(特殊)
ImageViewiv
ProgressBarpb
ListViewlv
GridViewgv
ScrollViewsv
LinearLayoutll
RelativeLayoutrl
ConstraintLayoutcl
FrameLayoutfl
RecyclerViewrv

属性排列#

规范布局控件的属性排列顺序,可以提高布局代码的可读性,维护性,提高团队协作的效率。排列顺序如下:
1. id
id
2. 宽高
layout_widthlayout_height
3. 位置
layout_abovelayout_belowlayout_toLeftOflayout_toRgithOflayout_gravitylayout_centerVerticallayout_centerInParentlayout_centerHorizontal 等)
4. 内外边距
layout_marginToplayout_marginBottomlayout_marginLeftlayout_marginRightpaddingToppaddingBottompaddingLeftpaddingRight
5. 其他
例:

  • 文字相关 (texttextColortextSize
  • 背景、图片资源 (backgroundsrc
  • 图片的缩放策略、文字的单行显示、超字数省略等等 (scaleTypesingleLineellipsize 等)

6. 可见性visibility
例:

<Button
android:id="@+id/btn_reload"
android:layout_width="100dp"
android:layout_height="30dp"
android:layout_below="@id/tv_blank_sub_title"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginTop="@dimen/common_margin_top"
android:background="@drawable/selector_btn_common_reload"
android:gravity="center"
android:text="@string/blankpage_net_work_btn_txt"
android:textColor="@color/common_warn_assist_font_color"
android:textSize="@dimen/common_font_size_15"
android:visibility="gone"
/>