一文讲解开发中的命名规范

news2024/9/27 7:16:02

命名规范

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

​ 在本文中,将从大到小,从外到内,总结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/809391.html

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

相关文章

java+springboot+mysql智慧办公OA管理系统

项目介绍&#xff1a; 使用javaspringbootmysql开发的智慧办公OA管理系统&#xff0c;系统包含超级管理员&#xff0c;系统管理员、员工角色&#xff0c;功能如下&#xff1a; 超级管理员&#xff1a;管理员管理&#xff1b;部门管理&#xff1b;职位管理&#xff1b;员工管理…

传输层中一些零碎且易忘的知识点

端口号&#xff1a;共两个字节 不同类型的端口号&#xff1a; 服务端端口号 熟知端口号&#xff1a;0&#xff5e;1023登记端口号&#xff1a;1024&#xff5e;49151 客户端使用端口号&#xff08;短暂/临时端口号&#xff09;&#xff1a;49152&#xff5e;65535 要记得常见应…

Linux之Shell 编程详解(一)

第 1 章 Shell 概述 1&#xff09;Linux 提供的 Shell 解析器有 [atguiguhadoop101 ~]$ cat /etc/shells /bin/sh /bin/bash /usr/bin/sh /usr/bin/bash /bin/tcsh /bin/csh2&#xff09;bash 和 sh 的关系 [atguiguhadoop101 bin]$ ll | grep bash -rwxr-xr-x. 1 root root …

EIP-2535 Diamond standard 实用工具分享

前段时间工作对接到了这标准的协议&#xff0c;于是简单介绍下这个标准分享下方便前端er使用的调用工具 一、标准的诞生 在写复杂逻辑的solidity智能合约时&#xff0c;经常会碰到两个问题&#xff0c;升级和合约大小限制。 升级目前有几种proxy模式&#xff0c;通过delegateca…

Minio在windows环境配置https访问

minio启动后&#xff0c;默认访问方式为http&#xff0c;但是有的时候我们的访问场景必须是https&#xff0c;浏览器有的会默认以https进行访问&#xff0c;这个时候就需要我们进行配置上的调整&#xff0c;将minio从http访问升级到https。而查看minio的官方文档&#xff0c;并…

基于Fringe-Projection环形投影技术的人脸三维形状提取算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 .................................................................... figure; imshow(Im…

JavaScript高级——ES6基础入门

目录 前言let 和 const块级作用域模板字符串一.模板字符串是什么二.模板字符串的注意事项三. 模板字符串的应用 箭头函数一.箭头函数是什么二.普通函数与箭头函数的转换三.this指向1. 全局作用域中的 this 指向2. 一般函数&#xff08;非箭头函数&#xff09;中的this指向3.箭头…

Android性能优化之SharedPreference卡顿优化

下面的源码都是基于Android api 31 1、SharedPreference使用 val sharePref getPreferences(Context.MODE_PRIVATE) with(sharePref.edit()) { putBoolean("isLogin", true)putInt("age", 18)apply() } val isLogin sharePref.getBoolean("isLogi…

Flink CEP(二) 运行源码解析

通过DemoApp学习一下&#xff0c;CEP的源码执行逻辑。为下一篇实现CEP动态Pattern奠定理论基础。 1. Pattern的定义 Pattern<Tuple3<String, Long, String>,?> pattern Pattern.<Tuple3<String, Long, String>>begin("begin").where(new…

MySQL检索数据和排序数据

目录 一、select语句 1.检索单个列&#xff08;SELECT 列名 FROM 表名;&#xff09; 2.检索多个列&#xff08;SELECT 列名1&#xff0c;列名2&#xff0c;列名3 FROM 表名;&#xff09; 3.检索所有的列&#xff08;SELECT * FROM 表名;&#xff09; 4.检索不同的行&#x…

【小白必看】Python图片合成示例之使用PIL库实现多张图片按行列合成

文章目录 前言效果图1. 导入必要的库2. 打开文件并获取大小3. 设置生成图片的行数和列数4. 获取所有图片的名称列表5. 创建新的画布6. 遍历每个位置并粘贴图片7. 保存合成的图片完整代码图片来源结束语 前言 本文介绍了一个用于图片合成的 Python 代码示例。该代码使用了PIL库来…

一篇文章搞定Java泛型

目录 介绍 优点 泛型类 语法定义 代码示例 泛型类注意事项 抽奖示例 泛型类派生子类 定义 代码示例 子类是泛型 子类不是泛型 泛型接口 定义 泛型方法 定义 代码示例 泛型方法与可变参数 泛型方法总结 ​编辑类型通配符 定义 代码示例 通配符的上限 定义 …

leetcode743. 网络延迟时间 floyd

https://leetcode.cn/problems/network-delay-time/ 有 n 个网络节点&#xff0c;标记为 1 到 n。 给你一个列表 times&#xff0c;表示信号经过 有向 边的传递时间。 times[i] (ui, vi, wi)&#xff0c;其中 ui 是源节点&#xff0c;vi 是目标节点&#xff0c; wi 是一个信…

详细介绍 React 中如何使用 redux

在使用之前要先了解它的配套插件&#xff1a; 在React中使用redux&#xff0c;官方要求安装其他插件 Redux Toolkit 和 react-redux Redux Toolkit&#xff1a;它是一个官方推荐的工具集&#xff0c;旨在简化 Redux 的使用和管理。Redux Toolkit 提供了一些提高开发效率的工具…

F5 LTM 知识点和实验 5-健康检测

第五章:健康检测 监控的分类: 地址监控(3层)服务监控(4层)内容监控(7层)应用监控(7层)性能监控(7层)路径监控(3、4、7层)三层监控: 三层监控可以帮助bipip系统通过检查网络是否可达监视资源。比如使用icmp echo,向监控节点发送icmp_echo报文,如果接收到响应…

求分享如何批量压缩视频的容量的方法

视频内存过大&#xff0c;不但特别占内存&#xff0c;而且还会使手机电脑出现卡顿的现象&#xff0c;除此之外&#xff0c;如果我们想发送这些视频文件可能还会因为内存太大无法发送。因此&#xff0c;我们可以批量地压缩视频文件的内存大小&#xff0c;今天小编要来分享一招&a…

车载软件架构 —— 信息安全与基础软件

车载软件架构 —— 信息安全与基础软件 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他人的角度来反对自己。人生在世,最怕…

郑州多域名https证书

多域名https证书是https证书中比较特殊的一款&#xff0c;它保护的域名记录是众多https证书中最灵活的。不管是DV基础型的多域名https证书还是OV企业型和EV增强型的多域名https证书既可以保护多个主域名或者子域名&#xff0c;还可以主域名子域名随意组合&#xff0c;只要申请者…

matlab--solve函数的用法

目录 1.用法结构 2.解单变量方程 3.解多变量方程 4.解带参方程 5.解不等式 6.总结 1.用法结构 solve函数是MATLAB中的一个符号计算函数&#xff0c;用于求解方程组或方程的符号解。 它的用法如下&#xff1a; 定义符号变量&#xff1a;使用syms函数定义符号变量&#…

CSDN博客置顶操作

目录 背景: 过程: 第一步: 第二步&#xff1a; 总结&#xff1a; 背景: 对于文章博主都想把优质的好文放在第一位与大家分享&#xff0c;让更多的人看到自己的文章以便更好的展现出来&#xff0c;那么就是置顶。 过程: 第一步: 打开CSDN主页文章&#xff0c;将鼠标放在…