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

news2024/11/16 19:41:30

命名规范

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

​ 在本文中,将从大到小,从外到内,总结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》
  • 《阿里巴巴开发规范》
  • 《阿里技术》

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络——学习笔记

付费版&#xff1a;直接在上面的CSDN资源下载 免费版&#xff1a;https://wwsk.lanzouk.com/ijkcj13tqmyb 示例图&#xff1a;

BIOS相关知识

简介 BIOS&#xff08;Basic Input Output System&#xff09;基本输入输出系统&#xff0c;固化在服务器主板的专用ROM中&#xff0c;是加载在服务器硬件系统上最基本的运行程序。BIOS位于硬件和系统中间&#xff0c;用来初始化硬件&#xff0c;为操作系统运行做准备 功能 …

C语言进阶——文件的打开(为什么使用文件、什么是文件、文件的打开和关闭)

目录 为什么使用文件 什么是文件 程序文件 数据文件 文件名 文件的打开和关闭 文件指针 打开和关闭 为什么使用文件 在之前学习通讯录时&#xff0c;我们可以给通讯录中增加、删除数据&#xff0c;此时数据是存放在内存中&#xff0c;当程序退出的时候&#xff0c;通讯…

【算法提高:动态规划】1.1 数字三角形模型

文章目录 例题列表1015. 摘花生1018. 最低通行费1027. 方格取数&#xff08;两条路径同时走&#xff09;⭐⭐⭐⭐⭐275. 传纸条&#xff08;转换成 两条路径同时走&#xff09; 例题列表 1015. 摘花生 https://www.acwing.com/problem/content/1017/ 状态要么从左转移过来&…

基于双层优化的大型电动汽车时空调度(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

❤️创意网页:贪吃蛇游戏 - 创造一个经典的小游戏

✨博主&#xff1a;命运之光 &#x1f338;专栏&#xff1a;Python星辰秘典 &#x1f433;专栏&#xff1a;web开发&#xff08;简单好用又好看&#xff09; ❤️专栏&#xff1a;Java经典程序设计 ☀️博主的其他文章&#xff1a;点击进入博主的主页 前言&#xff1a;欢迎踏入…

c++的函数定义中,只提供形参类型,不提供形参名

如上图所示&#xff0c;显示了 c 语法里的一种不常见的应用。若没有对某个形参的后续使用的要求&#xff0c;可以不提供形参名的&#xff0c;也能编译通过。这么写法的作用&#xff0c;可以以第一个参数的类型不同&#xff0c;来实现函数的重载。在阅读源码&#xff0c;在vs201…

【Linux】UDP协议

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录 &#x1f449;传输层&a…

目标检测应用场景—数据集【NO.14】行人跌倒测试

写在前面&#xff1a;数据集对应应用场景&#xff0c;不同的应用场景有不同的检测难点以及对应改进方法&#xff0c;本系列整理汇总领域内的数据集&#xff0c;方便大家下载数据集&#xff0c;若无法下载可关注后私信领取。关注免费领取整理好的数据集资料&#xff01;今天分享…

什么是线程?线程和进程的关系?如何创建/查看线程?

文章目录 一. 认识线程(Thread)1.1 概念1.1.1 什么是线程1.1.2 线程存在的意义1.1.3 进程和线程之间的区别和联系1.1.4 Java的线程和操作系统的线程 1.2 创建线程① 继承Thread类② 实现Runnable 接口对比两种方法③ 变形写法④ 其他写法 1.3 查看线程 一. 认识线程(Thread) 1…

C++之科学技术法e使用(一百七十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

阿里云服务器全方位介绍_性能功能优势和租用费用

阿里云服务器全方位介绍包括云服务器ECS优势、云服务器租用价格、云服务器使用场景及限制说明&#xff0c;阿里云服务器网分享云服务器ECS介绍、个人和企业免费试用、云服务器活动、云服务器ECS规格、优势、功能及应用场景详细说明&#xff1a; 目录 什么是云服务器ECS&#…

学习笔记22 set

一、概述 Set是一种集合类型&#xff0c;可以快速在大量数据中查找特定值。 Set存储无序序列中的元素&#xff0c;并且不允许重复。与列表不同&#xff0c;列表中的数据可以通过索引访问&#xff0c;但是在集合中&#xff0c;元素没有与集合中的位置相关联。 Set是优化了搜索…

消息队列总结(4)- RabbitMQ Kafka RocketMQ高性能方案

1.RabbitMQ的高性能解决方案 1.1 发布确认机制 RabbitMQ提供了3种生产者发布确认的模式&#xff1a; 简单模式&#xff08;Simple Mode&#xff09;&#xff1a;生产者发送消息后&#xff0c;等待服务器确认消息已经被接收。这种模式下&#xff0c;生产者发送消息后会阻塞&am…

M5ATOMS3基础03给ROS1发一个问候(rosserial)

引出问题 关于之前2020年的博客&#xff1a; 01. ESP8266和ROS调试一些问题汇总 02. ESP8266和ESP32配置&#xff08;需使用ROS1和ROS2&#xff09; 效果展示 使用M5ATOMS3与ROS1&#xff08;kinetic&#xff0c;melodic&#xff0c;noetic&#xff09;版本通信比较通用的是…

BUU [网鼎杯 2020 朱雀组]phpweb

BUU [网鼎杯 2020 朱雀组]phpweb 众生皆懒狗。打开题目&#xff0c;只有一个报错&#xff0c;不知何从下手。 翻译一下报错&#xff0c;data()函数:,还是没有头绪&#xff0c;中国有句古话说的好“遇事不决抓个包” 抓个包果然有东西&#xff0c;仔细一看这不就分别是函数和参…

【算法基础:贪心】6. 贪心

文章目录 区间问题905. 区间选点&#xff08;排序 贪心&#xff09;908. 最大不相交区间数量&#xff08;排序 贪心&#xff09;906. 区间分组&#xff08;排序 优先队列 贪心&#xff09;⭐907. 区间覆盖&#xff08;排序 贪心&#xff09; Huffman树148. 合并果子&#…

【LeetCode 75】第十四题(643)子数组最大平均数

题目: 示例: 分析: 给一个数组,问数组里长度为k的连续数组中的最大平均值是多少. 这题已经把意思说的很明白了,并且连子数组的长度都固定了,并且是连续的,这里可以直接使用固定长度的滑动窗口来计算. 用两个指针来在数组里划定一个长度为k的范围,然后计算指针范围内的平均数…

数组传参,指针传参

文章目录 一维数组传参二维数组传参一级指针传参二级指针传参 一维数组传参 二维数组传参 一级指针传参 二级指针传参

CentOS 8 上安装 Nginx

Nginx是一款高性能的开源Web服务器和反向代理服务器&#xff0c;以其轻量级和高效能而广受欢迎。在本教程中&#xff0c;我们将学习在 CentOS 8 操作系统上安装和配置 Nginx。 步骤 1&#xff1a;更新系统 在安装任何软件之前&#xff0c;让我们先更新系统的软件包列表和已安…