【编程规范】一文讲解开发中的命名规范

命名规范

好的代码本身就是注释, 所以我们需要统一命名风格。

​ 在本文中,将从大到小,从外到内,总结Java编程中的命名规范。文中将会涉及到日常工作中常见的命名示例,如包命名,类命名,接口命名,方法命名,变量命名,常类命名,抽象类命名,异常类命名以及扩展类命名等。我将按照项目工程目录结构,从包,类(接口,抽象类,异常类),方法,变量和常量的顺序展开介绍。

常量命名

1.命名说明

常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。

2.命名技巧

1、业务含义清晰。

在具名常量时,应该根据该常量所表示的含义,而不是该常量所具有的数值为该抽象事物命名。FIVE 是个很糟的常量名(不论它所代表的值是否为 5.0)。CYCLES_NEBDED 是个不错的名字。CYCLES_NEEDED 可以等于 5.0 或者 6.0。而 FIVE=6.0 就显得太可笑了。出于同样原因,BAKERS_DOZEN 就是个很糟的常量名;而DONUTS_MAX 则很不错。

2、允许任何魔法值(即未经定义的常量)直接出现在代码中。

3、long 或者 Long 初始赋值时,必须使用大写的 L,不能是小写的 l,小写容易跟数字 1 混淆,造成误解。

说明: Long a = 2l; 写的是数字的 21,还是 Long 型的 2?

4、不要使用一个常量类维护所有常量,应该按常量功能进行归类,分开维护。如: 缓存相关的常量放在类: CacheConsts 下;系统配置相关的常量放在类: ConfigConsts 下。
说明 : 大而全的常量类,非得使用查找功能才能定位到修改的常量,不利于理解和维护。

5、常量的复用层次有五层: 跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量。

  1. 跨应用共享常量(两个不同的应用): 放置在二方库中,通常是 client.jar 中的 constant 目录下。
  2. 应用内共享常量(同一个应用): 放置在一方库的 modules 中的 constant 目录下。
    反例 : 易懂变量也要统一定义成应用内共享常量,两位攻城师在两个类中分别定义了表示“是”的变量:
类 A 中: public static final String YES = "yes";  
类 B 中: public static final String YES = "y";  
A.YES.equals(B.YES),预期是 true,但实际返回为 false,导致线上问题。
  1. 同一个应用下的子工程内部共享常量: 即在当前子工程的 constant 目录下。
  2. 包内共享常量: 即在当前包下单独的 constant 目录下。
  3. 类内共享常量: 直接在类内部 private static final 定义。

变量命名

1.命名说明

变量名是名词,要正确和清晰地描述业务语义

2.命名技巧

1、业务含义清晰。避免无业务语义的命名,如:list、val、a...;

2、语境范围精准。

避免小范围词套大范围数据,反之亦然,不使用过于宽泛的名词,如:date 看上去不错,但经过最后推敲它也只是个坏名字,因为这里所说的日期并不是所有的日期均可,而只是特指当前日期;而 date 本身并未表达出这层含义。

3、名词复数。统一风格,加s或List尾缀,变量名建议使用s尾缀,函数名建议使用List尾缀;

4、前置对仗词。位于变量前置部分,用于修饰后面的名词。

  • begin/end:beginTime,endTime。
  • first/last
  • locked/unlocked
  • min/max
  • next/previous
  • old/new
  • opened/closed
  • visible/invisible
  • source/target
  • source/destination
  • up/down

5、后置限定词。描述名词的作用范围属性,例如:

  • 请求入参:xxxQuery/xxxRequest
  • 返回结果:xxxResponse/xxxResult
  • 传参数据:xxxDTO/xxxVO/xxxInfo
  • 运算结果:xxxTotal(总和)/xxxMax(最大值)/xxxAverage(平均值)

6、变量长度控制。

当变量名的平均长度在10 到16 个字符的时候,调试程序所需花费的气力是最小的(1990)。平均名字长度在8到20个字符的程序也几乎同样容易调试。这项原则并不意味着你应该尽量把变量名控制在9到15或者10到16 个字符长。它强调的是,如果你查看自己写的代码时发现了很多更短的名字,那么你需要认真检查,确保这些名字含义足够清晰。

7、为特定类型的数据命名。

在为数据命名的时候,除了通常的考虑事项之外,为一些特定类型数据的命名还要求做出一些特殊的考虑。下面将讲述与循环变量状态变量临时变量布尔变量枚举类型具名常量有关的考虑事项。

  1. 循环变量。无论循环体内还是循环体外,都应该给变量赋予更符合语义的名称,而不是用i、j、k潦草定义。
  2. 状态变量。为状态变量取一个比 flag 更好的名字 。最好是把标记(flag)看做状态变量,标记的名字中不应该含有 flag,因为你从中丝毫看不出该标记是做什么的。
    1. 坏的名字:statusFlag = 50。除非你亲自写了这段代码,或者有文档能告诉你 statusFlag 和 50的含义。
    2. 好的名字:dataReady = true;recalcNeeded = false。
  1. 临时变量。无。
  2. 布尔变量。
    1. 谨记典型的布尔变量名。done表示某件事情已经完成;error表示有错误发生;found表示已经找到值....
    2. 使用肯定语气的布尔变量名。否定的名字如 notFound、 notdone 以及 notSuccessful等较难阅读,特别是如果它们被求反:if not notFound。
  1. 为枚举变量命名。
    1. 常量池则添加组前缀。在使用枚举类型的时候,可以通过使用组前缀,如 Color_,Planet_或者Month_来明确表示该类型的成员都同属于一个组。下面举一些通过前缀来确定枚举类型元素的例子:Color_Red,Color_Blue...
    2. 枚举类则不添加前缀。 在有些编程语言里,枚举类型的处理很像类,枚举成员也总是被冠以枚举名字前缀,比如 Color.Color_Red 或者 Planet. Planet_Earth(java语言就是这样)。如果你正在使用这样的编程语言,那么重复上述前缀的意义就不大了,因此你可以把枚举类型自身的名字作为前缀,并把上述名字简化为 Color. Red 和 Planet. Earth。
  1. 具名常量。在具名常量时,应该根据该常量所表示的含义,而不是该常量所具有的数值为该抽象事物命名。FIVE 是个很糟的常量名(不论它所代表的值是否为 5.0)。CYCLES_NEBDED 是个不错的名字。CYCLES_NEEDED 可以等于 5.0 或者 6.0。而 FIVE=6.0 就显得太可笑了。出于同样原因,BAKERS_DOZEN 就是个很糟的常量名;而DONUTS_MAX 则很不错。

8、POJO、DO等实体类中的变量不要以is开头。有些框架解析的时候会出错。

9、RPC‘接口返回值’以及‘接口入参值’,禁止使用枚举;枚举在你的系统内部使用即可。推荐在这个字段上注释一个枚举类型。

3.基本数据类型

基本数据类型是构建其他所有数据类型的构造块 (building blocks )。本章包含了使用数(普遍意义上)、整数、浮点数、字符和字符串、布尔变量、枚举类型、具名常量以及数组的一些技巧。本章的最后一节将讲述如何创建自己的数据类型。

传送门 - 《代码大全2》第12章 基本数据类型

函数命名

1.命名说明

通常采用动词+名词。函数命名要体现做什么,而不是怎么做,要清楚表达出操作意图业务语义

2.命名技巧

1、动名词搭配,动词表达操作意图,名词表达业务语义。

public interface MemberFacade {
    /**
     * 查询会员信息
     * 
     * 命名的问题:
     *  1.没有表达操作意图:build是构建,没有表达查询的意图。
     *  2.没有表达业务语义:没有表达build的目标对象是什么。
     **/
    SingleResult<MemberDTO> build(MemberBuildRequest request);
    /**
     * 更新会员信息
     *
     * 命名的问题:
     *  1.没有表达业务语义:不知道具体更新会员的哪些信息
     *  2.操作意图表达过于宽泛:update可以把所有会员信息更新都放在这个函数里。
     **/
    SingleResult update(MemberUpdateRequest request);
}
public interface MemberFacade {
    /**
     * 查询会员信息
     **/
    SingleResult<MemberDTO> queryMember(MemberQuery query);
    /**
     * 更新会员昵称
     **/
    SingleResult updateNick(MemberUpdateRequest request);
}

2、名词复数。变量名建议使用s尾缀,函数名建议使用List尾缀;

3、正反操作使用对仗词,例如:

  • add/remove
  • open/close
  • begin/end
  • insert/delete
  • first/last
  • min/max

类命名

1.命名说明

类是面向对象中最重要的概念,是一组关联数据的相关操作的封装,通常可以把类分为两种:

1)实体类:通常采用名词承载业务的核心数据和业务逻辑,命名要充分体现业务语义,比如Order/Buyer/Item。

2)辅助类:通常采用名词+功能后缀协调实体类完成业务逻辑,命名通常加后缀体现出其功能性,比如OrderQueryService/OrderRepository。

2.命名技巧

1、辅助类尽量避免用 Helper/Util 之类的后缀,因为其含义过于笼统,容易破坏单一职责原则。

2、针对某个实体的辅助操作过多,或单个操作很复杂,可通过 “实体 + 操作类型 + 功能后缀”来命名,同时符合职责单一和接口隔离的原则,比如OrderService:

  • OrderCreateService:订单创建服务;
  • OrderUpdateService:订单更新服务;
  • OrderQueryService:订单查询服务。

3、如果使用了设计模式,类名中应该体现出具体的模式。将设计模式体现在名字中,有利于阅读者快速理解架构设计思想。

public class OrderFactory;
public class LoginProxy;
public class ResourceObserver;

接口命名

1.命名说明

接口(Interface)是一种表述某一类型对象动作的特殊类;简单来说,接口也是类(不太严谨),所以,接口的名称的书写也应该符合类名书写规范。

与普通类名不同的是,接口命名时通常采用形容词动词来描述接口的动作行为,也可以配合名词一起使用。

2.命名技巧

1、可以interface后缀结尾。

2、Oracle Java中一些标准库的接口使用形容词命名示例:

public interface Closeable{
    //...
}
public interface Cloneable{
    //...
}
public interface RunnableP{
    //...
}
public interface Comparable<T>{
    //...
}
public interface CompletionService<V>{
    //...
}
public interface Iterable<T>{
    //...
}
public interface EventListener{
    //...
}

3、在Spring Framework标准库中,通常采用名词+动词/形容词的组合方式来命名接口,下列是Spring Framework中一些接口命名示例:

public interface AfterAdvice{
    //...
}
public interface TargetClassAware{
    //...
}
public interface ApplicationContextAware{
    //...
}
public interface MessageSourceResolvable{
    //...
}

抽象类命名

1.命名说明

抽象类(Abstract Class)是一种特殊的类,其命名与普通类的命名规范相当。

一般地,为了将抽象类与普通类和接口做出区别,提高抽象类的可读性,在命名抽象类时,会以“Abstract”/“Base”作为类命的前缀。

2.命名技巧

1、以“Abstract”/“Base”作为类命的前缀。

2、编程中一些常规的命名示例:

public abstract class AbstractRepository<T>{
    //...
}
public abstract class AbstractController{
    //...
}
public abstract class BaseDao<T,ID>{
    //...
}
public abstract class AbstractCommonService<T>{
    //...
}

3、Spring Framework中常见的抽象类示例:

public abstract class AbstractAspectJAdvice{
    //...
}
public abstract class AbstractSingletonProxyFactoryBean{
    //...
}
public abstract class AbstractBeanFactoryPointcutAdvisor{
    //...
}
public abstract class AbstractCachingConfiguration{
    //...
}
public abstract class AbstractContextLoaderInitializer{
    //...
}

异常类命名

1.命名说明

异常类(Exception Class)也是类的一种,但与普通类命名不同的是,异常类在命名时需要使用“Exception”作为其后缀。

另外,在Java中还有另外一类异常类,它们属于系统异常,这一类异常类的命名使用“Error”作为其后缀,以区分Exception(编码,环境,操作等异常)。

2.命名技巧

1、Exception或者Error结尾。

2、exception示例:

public class FileNotFoundException{
    //...
}
public class UserAlreadyExistException{
    //...
}
public class TransactionException{
    //...
}
public class ClassNotFoundException{
    //...
}
public class IllegalArgumentException{
    //...
}
public class IndexOutOfBoundsException{
    //...
}

3、error示例:

public abstract class VirtualMachineError{
    //...
}
public class StackOverflowError{
    //...
}
public class OutOfMemoryError{
    //...
}
public class IllegalAccessError{
    //...
}
public class NoClassDefFoundError{
    //...
}
public class NoSuchFieldError{
    //...
}
public class NoSuchMethodError{
    //...
}

测试类命名

1.命名说明

在项目中,测试类采用被测试业务模块名/被测试接口/被测试类+“Test”后缀的方法进行书写,测试类中的测试函数采用“test”+用例操作_状态的组合方式进行书写。

2.命名技巧

1、测试类以Test结尾。

2、测试方法test+用例操作_状态。如:

public class UserServiceTest{

    public void testFindByUsernameAndPassword(){
        //...
    }

    public void testUsernameExist_notExist(){
        //...
    }

    public void testDeleteById_isOk(){
        //...
    }
}

包命名

1.命名说明

通常,包命使用小写英文字母进行命名,并使用“.”进行分割,每个被分割的单元只能包含一个名词

一般地,包命名常采用顶级域名作为前缀,例如com,net,org,edu,gov,cn,io等,随后紧跟公司/组织/个人名称以及功能模块名称。

package org.springframework.boot.autoconfigure.cloud
package org.springframework.boot.util
package org.hibernate.action
package org.hibernate.cfg
package com.alibaba.druid
package com.alibaba.druid.filter
package com.alibaba.nacos.client.config
package com.ramostear.blog.web

2.命名技巧

1、包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。

2、包的命名要大小适中,不能太具体,也不能太抽象。

  1. 比如类Apple、Orange都是水果,可以收纳进fruit包内。
  2. 比如包名叫Apple,太具体导致类Orange放不进去。
  3. 又比如包名叫food,太抽象导致其他非水果也被放进来了。

3、实际工程中,常见的分类维度主要是两种,按功能性或业务域分类。

  • 功能性分类:metaq、mapper、service、dao等;
  • 业务域分类:user、item、order、promotion等。

4、同一层级的包,要严格保持分类维度的一致性,要么先按业务域分类,再按功能性分类;要么就先按功能性分类,再按业务域分类。

client
  |----request
          |----order
          |----item
  |----response
          |----order
          |----item
  |----service
          |----OrderQueryService.java
          |----ItemQueryService.java

其他命名规范

泛型命名

在书写泛型类时,通常做以下的约定:

  • E表示Element,通常用在集合中;
  • ID用于表示对象的唯一标识符类型
  • T表示Type(类型),通常指代类;
  • K表示Key(键),通常用于Map中;
  • V表示Value(值),通常用于Map中,与K结对出现;
  • N表示Number,通常用于表示数值类型;
  • ?表示不确定的Java类型;
  • X用于表示异常;
  • U,S表示任意的类型。

下面时泛型类的书写示例:

public class HashSet<E> extends AbstractSet<E>{
    //...
}
public class HashMap<K,V> extends AbstractMap<K,V>{
    //...
}
public class ThreadLocal<T>{
    //...
}
public interface Functor<T,X extends Throwable>{
    T val() throws X;
}
public class Container<K,V>{
    private K key;
    private V value;
    Container(K key,V value){
        this.key = key;
        this.value = value;
    }
    //getter and setter ...
}
 
public interface BaseRepository<T,ID>{
    T findById(ID id);
 
    void update(T t);
 
    List<T> findByIds(ID...ids);
}
 
public static <T> List<T> methodName(Class<T> clz){
    List<T> dataList = getByClz(clz);
    return dataList;
}

参考资料

  • 《代码大全2》
  • 《阿里巴巴开发规范》
  • 《阿里技术》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/51526.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

页面生成图片或PDF node-egg

没有特别的幸运&#xff0c;那么就特别的努力&#xff01;&#xff01;&#xff01; 中间件&#xff1a;页面生成图片 node-egg 涉及到技术node egg Puppeteer 解决文书智能生成多样化先看效果环境准备初始化项目 目录结构核心代码 完整代码https://gitee.com/hammer1010_ad…

数组中出现次数超过一半的数字——剑指 Offer 39

文章目录 题目描述法一 哈希表法二 摩尔投票 题目描述 法一 哈希表 使用哈希映射&#xff08;HashMap&#xff09;来存储每个元素以及出现的次数。对于哈希映射中的每个键值对&#xff0c;键表示一个元素&#xff0c;值表示该元素出现的次数。 class Solution { public:int maj…

【Python机器学习】实验03 logstic回归

文章目录 简单分类模型 - 逻辑回归1.1 准备数据1.2 定义假设函数Sigmoid 函数 1.3 定义代价函数1.4 定义梯度下降算法gradient descent(梯度下降) 1.5 绘制决策边界1.6 计算准确率1.7 试试用Sklearn来解决2.1 准备数据(试试第二个例子)2.2 假设函数与前h相同2.3 代价函数与前相…

【语音识别】- 声学,词汇和语言模型

一、说明 语音识别是指计算机通过处理人类语言的音频信号&#xff0c;将其转换为可理解的文本形式的技术。也就是说&#xff0c;它可以将人类的口语语音转换为文本&#xff0c;以便计算机能够进一步处理和理解。它是自然语言处理技术的一部分&#xff0c;被广泛应用于语音识别助…

Linux 之 systemctl

systemctl 可以控制软件&#xff08;一般指服务&#xff09;的启动、关闭、开机自启动 能被systemctl 管理的软件&#xff0c;一般也称 服务 系统内置服务均可被 systemctl 控制第三方软件&#xff0c;如果 自动注册了 可被systemctl 控制第三方软件&#xff0c;如果没有自动…

better scoll右 联左

这是先拿一个数组装进我们所有 获取到的dom节点的 高度 因为算的 都是 到最上面的 高度&#xff0c;所以我们 要减去他的 高度 就得到自身的高度 然后给右边加一个滚动事件&#xff0c;得到每一次滑动的高度&#xff0c;在循环上面的数组&#xff0c;就是我们右边的 y就在算出…

微信小程序实现日历功能、日历转换插件、calendar

文章目录 演示htmlJavaScript 演示 效果图 微信小程序实现交互 html <view wx:if"{{calendarArr.length}}"><view class"height_786 df_fdc_aic"><view class"grid_c7_104"><view class"font_weight_800 text_align…

Debezium日常分享系列之:定制Debezium 信号发送和通知

Debezium日常分享系列之&#xff1a;定制Debezium 信号发送和通知 一、自定义信号和通知通道二、结论 Debezium 2.3 在信号和通知功能方面引入了新的改进。除了 Debezium 提供的预定义信号和通知通道之外&#xff0c;您还可以设置新的信号和通知通道。此功能使用户能够自定义系…

微服务——服务异步通讯RabbitMQ

前置文章 消息队列——RabbitMQ基本概念容器化部署和简单工作模式程序_北岭山脚鼠鼠的博客-CSDN博客 消息队列——rabbitmq的不同工作模式_北岭山脚鼠鼠的博客-CSDN博客 消息队列——spring和springboot整合rabbitmq_北岭山脚鼠鼠的博客-CSDN博客 目录 Work queues 工作队列…

JS——输入输出语法数组的操作

JavaScript输入输出语法 目标&#xff1a;能写出常见的JavaScript输入输出语法 输出语法 语法1&#xff1a; document.write(要输出的内容)作用&#xff1a; 向body内输出内容 注意&#xff1a; 如果输出的内容写的是标签&#xff0c;也会被解析成网页元素 语法2&#xff1a…

Verilog语法学习——LV9_使用子模块实现三输入数的大小比较

LV9_使用子模块实现三输入数的大小比较 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 描述 在数字芯片设计中&#xff0c;通常把完成特定功能且相对独立的…

特殊矩阵的压缩存储

1 数组的存储结构 1.1 一维数组 各数组元素大小相同&#xff0c;且物理上连续存放。第i个元素的地址位置是&#xff1a;a[i] LOC i*sizeof(ElemType) (LOC为起始地址) 1.2 二维数组 对于多维数组有行优先、列优先的存储方法 行优先&#xff1a;先行后列&#xff0c;先存储…

无涯教程-jQuery - Select menu组件函数

小部件选择菜单功能可与JqueryUI中的小部件一起使用&#xff0c;它提供了可替换样式的选择元素。一个简单的选择菜单如下所示。 Select menu - 语法 $( "#menu" ).selectmenu(); Select menu - 示例 以下是显示选择菜单用法的简单示例- <!doctype html> &…

自动驾驶感知系统-全球卫星定位系统

卫星定位系统 车辆定位是让无人驾驶汽车获取自身确切位置的技术&#xff0c;在自动驾驶技术中定位担负着相当重要的职责。车辆自身定位信息获取的方式多样&#xff0c;涉及多种传感器类型与相关技术。自动驾驶汽车能够持续安全可靠运行的一个关键前提是车辆的定位系统必须实时…

Go语言进阶 + 依赖管理

依赖配置 - version开始&#xff0c;就开始很难听懂了&#xff0c;需要结合很多课后配套资料查阅很多文档和网站....然而好像没有那么多时间&#xff0c;一天给3小时学Go真的顶天了.....还有算法和Linux的Mysql... 这几天学Go已经把算法给挤掉了.....下步要权衡一下&#xff0c…

Centos7中实现脚本使用mysqldump实现分库分表备份

脚本 #!/bash/bin userroot #用户名 password123456 #密码 back_path/backup/db databases_file/backup/databases.list [ -f $databases_file ] || touch /backup/databases.list if [[ ! -s ${databases_file} ]] then while read line do[ -d ${back_path}/$line ] …

ERROR in unable to locate ‘***/public/**/*‘ glob

前提 自己搭了一个react项目的脚手架&#xff0c;npm包下载一切都很正常&#xff0c;启动的时候突然就报ERROR in unable to locate ***/public/**/* glob这个错误&#xff0c;根据百度分析了一下产生的原因&#xff1a;webpack配置文件中的CopyWebpackPlugin导致的 网上给出的…

C语言指针应该这么学?

数组名的意义&#xff1a; 1. sizeof(数组名)&#xff0c;这里的数组名表示整个数组&#xff0c;计算的是整个数组的大小。 2. &数组名&#xff0c;这里的数组名表示整个数组&#xff0c;取出的是整个数组的地址。 3. 除此之外所有的数组名都表示首元素的地址。 根据以上数…

用asp.net开发h5网页版视频播放网站,类似优酷,jellyfin,emby

之前用jellyfin开源软件搞了一个视频播放服务器,用来共享给家里人看电影和电视剧,jellyfin虽然各方面功能都很强大,但是界面和使用习惯都很不适合,于是就想着利用下班休息时间做一套自己喜欢的视频网站出来. 本来是打算直接用jellyfin的源码进行修改,源码是用C# netcore 写的服…

【C++进阶:哈希--unordered系列的容器及封装】

本课涉及到的所有代码都见以下链接&#xff0c;欢迎参考指正&#xff01; practice: 课程代码练习 - Gitee.comhttps://gitee.com/ace-zhe/practice/tree/master/Hash unordered系列关联式容器 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在…