笔者在公司里面写的内容,本文经过部分删减。

命名规范

# 1. 属性/成员 命名

  • 静态常量属性 即使用 static final 修饰的属性, 属性名全部大写并添加javadoc的注释。 比如下面的例子

    •     /**
           * 消息的线程数量
           */
          public static final int MSG_THREAD_NUM = 8;
          
          /**
           * redis 连接池的 线程数量
           */
          public static final int REDIS_CONNECTION_POOL_SIZE = 4;
          
      
  • 私有的实例属性 采用 驼峰命名法。 并需要使用单行注释 简单说明下含义、

    • 经常出现的变量名可以不写注释。
    • Map Or MapSubMap 需要写明 keyvalue的含义。
    • 如果是关键字开头的命名,比如 do ,for 可用_ 下划线开头, 比如_forConsole, _doWorkTime 尽量不要使用这种关键字开头的命名 😄
  • 方法名采用 驼峰命名法, 并需要添加 javadoc 注释, 在必要的时候 也需要写明参数的含义。

  • 公有静态变量, 首字母大写。 私有的静态属性采用驼峰命名法。

# 2. 选取有意义的命名

  • 要选取有意义的名称。
    • 下面的名称是可取的 👍👍👍
      • PlayerInfo getPlayer(String roleId); // 1
      • PlayerInfo getPlayerByRoleId(String str); // 2
    • 下面的名称是 不可取的 🙅‍♂️🙅‍♂️🙅‍♂️
      • PlayerInfo getPlayer(String str); // 3
      • PlayerInfo getPlayerByString(String str); // 4
  • 上述示例中, 1和2 都是自解释的方法签名, 一看就知道该方法的作用是根据roleId获取一个玩家对象。
  • 3和4 则不是自解释的。 我们目前无法得知参数需要的是roleId 还是 roleName, 亦或是其他什么属性。
    • 这时候如果方法还没有注释, 我们就必须要打开源代码去确认方法的作用了。
  • 有意义的类名也比较重要。
    • ConfigManagerSessionManager 就是比较有意义的名称。 如果我们需要一个配置文件的数据,我们将会知道从ConfigManager中获取,而非SessionManager
    • 同样,如果我们需要给某个玩家发送消息,则我们知道SessionManager类里面应该有这样一个方法。
    • 如果你看不懂上述说明, 则你可能需要加强一下你的英语了。
      • Config - 配置; 配置文件; 布局;
      • Session - 会话; 会议; 会期;
      • 上述内容来自 网易有道词典
    • 相对来说, 如果把玩家会话相关的内容放到一个叫做BananaManager 的类里面, 看到的人可能就会非常困惑: 我们项目里面有香蕉吗? 为什么要管理香蕉? 而在使用的时候,也增加了记忆的负担。
  • 如果一个类里面的功能过于复杂, 起一个有意义的类名 可能就比较困难了。此时,较好的做法是根据逻辑或者其他规则划分类的内容 进行重构。
  • 还有一种做法是笔者特别讨厌的。。 即 复制代码的时候只修改内容,不修改名称。
    • 如果一个方法的内容和你的需求类似, 但不完全相同。 首选的处理方式是 以添加参数或者拆分方法的形式进行处理, 而非复制一份,然后稍微修改下。
    • 如果你非要复制一份进行修改, 也是可以的(非常勉强的情况下 才能视为 可以)。 当出现这种情况的时候,你一定要修改方法的名字。
    • 比如一个在类A里方法:List<PlayerInfo> findPlayers(String roleId); 你将它复制到了类B里面的时候,把检测roleId的地方换成了 roleName, 但是你却没有修改方法名。 当这种情况出现的时候, 别人在使用这些方法的时候就会出错, 他们同样也会很困惑。
    • 笔者有个同事简直更离谱,有时候方法名和方法内容会出现完全没有关系情况, 当笔者问他的时候,他会回答说『哦,我复制的』😶😶😶 (该同事目前已经离开了笔者所在的公司。

其他要点

# 1.注释

规则

  • 注释部分是一定要写的, 但是不必写的特别详细。

  • 一般来说, 除非方法名是自解释的,否则一定要加上注释。 参数名若有歧义也需要加上注释。

  • 类的实例属性也需要加上注释。 使用 // 的单行注释即可

  • 类,类的实例方法, 静态方法,静态属性尽量加上注释, 注释采用 javadoc的风格。 若名称带有歧义,则一定 要加上注释。

  • 方法内的逻辑若十分复杂, 流程较长也需要添加注释。

  • 数据库里的数据表字段, 也需要适当的添加注释。

  • 对于部分int类型字段, 可能需要添加释义。 比如性别: 0未知,1女,2男等

  • 对于部分Map 类型的字段, 需要指定Key以及Value的含义。 比如玩家会话map, key: 玩家id, value: 会话信息

好处

这里用小A代指一个写了注释的同事。

  • 在同事B接手小A的工作的时候,同事B不需要和小A有太多交流就可以完成他的工作。 这样节省了小A和同事B两人的时间。 ⏱️⏱️⏱️

  • 在同事B需要调用小A写的接口的时候,也不需要打扰到小A。 这同样会节省较多时间。

  • 节省了时间意味着什么呢?

    • 你完全可以不用加班, 或者只需要少量加班。
    • 当你在上班的时候空闲了下来, 你可以去学习一些新技术, 去聊天群吹水, 甚至看看小说漫画。
    • 项目周期可能会缩短一些, 也可能会提前拿到一些奖金。
  • 注释可以帮助小A 更好的回忆几个月之前写的逻辑。

  • 在小A因为某些原因辞职的时候,甚至不需要写交接文档,辞职需要的时间也大大的缩减了。

# 2.代码块

  • 代码分块, 不要全部的逻辑写在一起, 不要写成一大坨的样子。
    • 基本的分块逻辑是按照类别和功能划分, 比如声明语句放在一些, 一个小功能的内容放在一起。 中间使用一行空行分割。 声明语句块之外的其他代码块 应该适当的添加一些单行注释,表明下面的代码是用来做什么的。
    • 如果可以的话, 分成若干个小方法也可以。
    • 这样做的好处是 便于观看,修改。 (我想,你也不愿意修了1个bug,又添加了3个把。。
  • if,else, while, for 等关键字,都需要添加 {}用于区分。 即使关键字后只有一条语句也需要添加。
    • 这样做会使代码风格统一, 且不会出现不必要的麻烦或者问题。
    • 使用Idea的时候,快捷键CMD/CTRL+SHIFT+ENTER 会自动追加 {} 也不需要手动添加。

# 3. 杂项

  • Tab 设置成 4个空格 , 部分IDE默认情况应该是这个,不需要修改。