# parim-spark 工程数据字典生成说明

## 目录

- [parim-spark 工程数据字典生成说明](#parim-spark-工程数据字典生成说明)
    - [目录](#目录)
    - [生成过程、原理](#生成过程原理)
        - [注释规约](#注释规约)
        - [Entity 实体类的 javadoc 注释规范](#entity-实体类的-javadoc-注释规范)
            - [单行注释](#单行注释)
            - [多行注释](#多行注释)
            - [Enum 注释](#enum-注释)
            - [注释示例](#注释示例)
            - [常见错误](#常见错误)
        - [Java 文件一般性注释规约](#java-文件一般性注释规约)
    - [字典生成方法](#字典生成方法)

## 生成过程、原理

目前 parim-spark 工程数据库表结构的创建和维护是依据 JPA 规范，根据工程中 Entity 实体类来自动维护生成的。Entity 实体类中包含了数据库表结构的全部信息，也是被优先、经常维护的，因此也包含了数据库表结构的最新信息。基于此，数据字典也选择以 Entity 实体类文件中的信息为基础来生成。

生成逻辑使用 groovy 语言，写在 gradle 配置文件 ```build_dict.gradle``` 中。原理为扫描工程中所有 Entity 实体类文件，逐个解析每个 Entity 实体类文件内容，按照 Entity 实体类文件中的注释、注解的语法和语义，抽取有用信息，然后以 Markdown 格式写入 ```src/doc/dictionary/data_dictionary.md``` 文件中，后续可借助其他第三方工具进一步生成 html、pdf 等格式文件方便使用或交付客户。

生成时直接使用工程自带的 ```gradlew``` 命令来执行，具体调用方法详见 [字典生成方法](#字典生成方法) 部分。

### 注释规约

### Entity 实体类的 javadoc 注释规范

Entity 实体类、类属性必须要有注释，注释必须使用 Javadoc 规范，使用 ```/** 内容 */``` 格式，不得使用 ```// xxx``` 方式和 ```/* xxx */``` 方式。

#### 单行注释

单行 javadoc 注释以 ```/**``` 开始，以 ```*/``` 结束。示例如下：

``` java
/** something */
```

* 注意：单行 Javadoc 注释 ```/**``` 后和 ```*/``` 前都应有一个空格。

#### 多行注释

多行 javadoc 注释示例如下：

``` java
/**
 * 系统数据字典分组表
 * 国际化配置通用key为<code>system.setting.dict.group.</code>
 *
 * @author jiawei
 */

```

* 注意：
  * 多行 javadoc 注释 ```/**``` 独占一行，其他行以 ```*``` 号+空格开始，最后以。
  * 每行第一个 ```*``` 号要对齐，最后的 ```*/``` 要另起一行。
  * 每一个 @ 标签必须在一个新行上。

#### Enum 注释

Enum 类型和其属性的 javadoc 注释示例如下：

``` java
    /**
     * 订单状态枚举类
     */
    public enum OrderStatus {
        /** 支付中 */
        WAIT,
        /** 支付成功 */
        SUCCESS,
        /** 支付失败 */
        FAIL
    }

    /**
     * 订单状态
     */
    @ColumnDefault("'WAIT'")
    @Enumerated(EnumType.STRING)
    private OrderStatus status;

```

#### 注释示例

![注释示例](img/right_example_1.png)

请参考```spark-market/market-provider/src/main/java/net/parim/spark/market/entity/Order.java```文件。

#### 常见错误

![常见错误](img/wrong_example_1.png)

### Java 文件一般性注释规约

此部分节选自《阿里巴巴JAVA开发手册v1.3.1》。

1. 【强制】类、类属性、类方法的注释必须使用 Javadoc 规范,使用 ```/** 内容 */``` 格式,不得使用 ```// xxx``` 方式。

    说明:在 IDE 编辑窗口中,Javadoc 方式会提示相关注释,生成 Javadoc 可以正确输出相应注 释;在 IDE 中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高 阅读效率。

2. 【强制】所有的抽象方法(包括接口中的方法)必须要用 Javadoc 注释、除了返回值、参数、 异常说明外,还必须指出该方法做什么事情,实现什么功能。 说明:对子类的实现要求,或者调用注意事项,请一并说明。

3. 【强制】所有的类都必须添加创建者和创建日期。

4. 【强制】方法内部单行注释,在被注释语句上方另起一行,使用 ```//注释```。方法内部多行注释使用 ```/* */``` 注释,注意与代码对齐。

5. 【强制】所有的枚举类型字段必须要有注释,说明每个数据项的用途。

6. 【推荐】与其“半吊子”英文来注释,不如用中文注释把问题说清楚。专有名词与关键字保持 英文原文即可。

    反例:“TCP 连接超时”解释成“传输控制协议连接超时”,理解反而费脑筋。

7. 【推荐】代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑 等的修改。

    说明:代码与注释更新不同步,就像路网与导航软件更新不同步一样,如果导航软件严重滞后, 就失去了导航的意义。

8. 【参考】谨慎注释掉代码。在上方详细说明,而不是简单地注释掉。如果无用,则删除。 说明:代码被注释掉有两种可能性:1)后续会恢复此段代码逻辑。2)永久不用。前者如果没 有备注信息,难以知晓注释动机。后者建议直接删掉(代码仓库保存了历史代码)。

9. 【参考】对于注释的要求:第一、能够准确反应设计思想和代码逻辑;第二、能够描述业务含义,使别的程序员能够迅速了解到代码背后的信息。完全没有注释的大段代码对于阅读者形同天书,注释是给自己看的,即使隔很长时间,也能清晰理解当时的思路;注释也是给继任者看的,使其能够快速接替自己的工作。

10. 【参考】好的命名、代码结构是自解释的,注释力求精简准确、表达到位。避免出现注释的一个极端:过多过滥的注释,代码的逻辑一旦修改,修改注释是相当大的负担。

    反例:

    ``` java
    // put elephant into fridge
    put(elephant, fridge);
    ```

    方法名 put,加上两个有意义的变量名 elephant 和 fridge,已经说明了这是在干什么,语义清晰的代码不需要额外的注释。

11. 【参考】特殊注释标记,请注明标记人与标记时间。注意及时处理这些标记,通过标记扫描, 经常清理此类标记。线上故障有时候就是来源于这些标记处的代码。

    1) 待办事宜(TODO): (标记人,标记时间,[预计处理时间]) 表示需要实现,但目前还未实现的功能。这实际上是一个 Javadoc 的标签,目前的 Javadoc 还没有实现,但已经被广泛使用。只能应用于类,接口和方法(因为它是一个 Javadoc 标签)。
    2) 错误,不能工作(FIXME):(标记人,标记时间,[预计处理时间])在注释中用 FIXME 标记某代码是错误的,而且不能工作,需要及时纠正的情况。

## 字典生成方法

进入工程根目录

``` bash
cd ~/git/parim-spark
```

在 parim-spark 工程根目录执行如下命令

``` bash
./gradlew :dict
```

* Windows 操作系统中如果是 git bash 中可使用和上面同样的命令；如果是在 cmd 或 power shell 命令行窗口，执行如下命令

``` bat
gradlew.bat :dict
```

执行完成后，将会生成 ```src/doc/dictionary/data_dictionary.md``` 文件，后续可借助其他第三方工具生成 html、pdf 等格式文件方便使用。

例如使用 vscode 上的 Markdown Preview Enhanced 插件可方便生成 html、pdf 等格式的离线文件。

对 ```spark-market/market-provider/src/main/java/net/parim/spark/market/entity/Order.java``` 文件生成的样例如下：

![生成样例](img/demo_result_1.png)
