Skip to content

HugeGraph代码风格指南

Linary edited this page Mar 5, 2019 · 4 revisions

1.行长度

建议80以内。

Eclipse、Idea等IDE均可针对项目进行设置,下文所述的换行对齐规则一般IDE也可设置。

好处:

  • 便于阅读
  • 命令行及Github可一行容纳下
  • 符合流行社区习惯

2.对齐与缩进

对于字符串和函数参数,对齐优先级高于缩进。也就是说换行时,如果能与上一行同类代码对齐则尽量对齐。

2.1 多条件if语句换行对齐

这里为了美观忽略百度内部规范:多条件并列时,建议逻辑运算符写在行尾,下行条件与上行括号对齐。如:

if (query.condition(HugeKeys.SOURCE_VERTEX) != null &&
    query.condition(HugeKeys.DIRECTION) != null &&
    !keys.isEmpty() && query.matchUserpropKeys(keys)) {

2.2 长函数参数换行对齐

建议括号内的逗号处换行。如: 注:不同浏览器上对齐效果可能不一致,两个Set首字母是竖直对齐的。

protected void prepareAdditions(Set<HugeVertex> updatedVertexes,
                                Set<HugeEdge> updatedEdges) {

另外throws换行对齐是与函数参数保持一致。

2.3 函数调用换行参数对齐

建议括号内的逗号处换行,如:

instance.longFunction(param1,
                      param2);
instance.longLongFunction(
         param1,
         param2);

2.4 长字符串换行对齐

建议在明显分隔符出换行,如逗号后,且空格保留在上行。如果能在第二行容纳得下所有内容,则第一行空着以保留完整字符串。如:

throw new BackendException(
          "Not support querying by multi edge-labels");

2.5 三元表达式换行对齐

保持与条件判断语句风格一致,符号写在行末,两个分支都另起一行

Number n1 = (first instanceof Number) ?
            (Number) first :
            toBig.apply(first);

3.空行

为了直观区分各个代码块,如下情况需要添加空行:

  • package下一行
  • class、enum定义的前一行和后一行
  • 成员变量定义完成与方法定义开始之间加空行
  • 方法定义、内部类定义、静态代码块等,它们之间加空行
  • 文件末尾保持一行空行
  • 方法内部逻辑相对独立的代码块使用空行分隔

4.变量、方法命名

  • 变量、方法命名:驼峰命名,保持与Google规范一致即可。
  • 方法前缀:方法名不需要get、set、is前缀,以保持方法名称的简洁。

5.逻辑if-return问题

关于if-return-else-return语句的清理咱们遵循的原则是:简短的错误处理代码放在方法体前部,if后直接return,后面不接else;如果是并列的业务逻辑代码,可使用if-return else-if-return else-return以使得逻辑更加清晰;关于是否判断为并列逻辑,如果没有明显的边界,那么倾向使用原则1。

https://softwareengineering.stackexchange.com/questions/157407/best-practice-on-if-return https://blog.mozilla.org/nnethercote/2009/08/31/no-else-after-return-considered-harmful/ http://newicafe.baidu.com/issue/HugeGraph-114/show?from=page

6.注释风格

  • 注释写在代码上面,不要写在代码右边或下面

  • 一行注释用//,多行注释用/**/

  • 类的注释和方法的注释都使用java-doc的写法,即:

    /**
     * xxx
     */
  • 方法内的注释使用首行单星号的多行注释,即:
    /*
     * xxx
     * xx
     */

7.错误检查

错误检查建议使用:E.checkArgument()E.checkState()等工具函数代替if + throw的方式。

E.checkArgument(!primaryKeyIds.contains(propKey.id()),
                "Can't remove primary key '%s'", propKey);
 
E.checkState(prop.element() != null,
             "No owner for removing property '%s'", prop.key());

事实上com.baidu.hugegraph.util.E直接调用com.google.common.base.Preconditions,错误检查需频繁使用,使用"E"代替"Preconditions"的原因是为了减少代码的长度。

8.异常处理

异常的处理一般在最上层调用处进行,或者外部API调用处进行。 如果进行异常转换时,建议通过日志打印原始异常的堆栈信息,或者将原始异常作为新异常的cause以记录异常栈。

try {
    return new GraphTransaction(this, this.loadGraphStore());
} catch (BackendException e) {
    String message = "Failed to open graph transaction";
    LOG.error("{}", message, e);
    throw new HugeException(message);
}

不允许存在吞异常的行为,吞异常会导致上层逻辑混乱:

try {
    return new GraphTransaction(this, this.loadGraphStore());
} catch (BackendException e) {
    e.printStackTrace();
}

如果明确的可以忽略异常,请使用"ignored"进行说明try {...} catch (XxException ignored) {}

9.日志打印

日志实例统一使用LOG命名,通过Log.logger()获取:

private static final Logger LOG = Log.logger(HugeGraph.class);

日志打印需要"{}"作为填充,而不是使用字符串拼接。

LOG.info("Opening backend store '{}' for graph '{}'",
         backend, this.name);

事实上com.baidu.hugegraph.util.Log直接调用org.slf4j.LoggerFactory,日志需频繁使用,使用"Log"代替"LoggerFactory"的原因依然是为了减少代码的长度。

10.字符串拼接

建议优先使用String.format()进行字符串拼接,以增强代码可读性。

String message = String.format("Graph '%s' start backup!", this.graph);

不允许在打印日志或错误检查时拼接字符串,以避免无谓的浪费。

LOG.debug("Do query: " + query);
E.checkArgument(!query.empty(), "The query is empty: " + query);

11.其它

其它未提及方面请以Google Java Style Guide为准。

You can’t perform that action at this time.