• 写代码时候的命名规则、命名规范、命名常用词汇


    版权声明
    这个大部分笔记是观看up主红桃A士的视频记录下来的,因为本人在学习的过程中也经常出现类似的问题,并且觉得Up主的视频讲解很好,做此笔记反复学习,若有侵权请联系删除,此推荐视频地址:【改善丑陋的代码】 https://www.bilibili.com/video/BV1844y1N7S8/p=28&share_source=copy_web&vd_source=688b3f7cfe13111b787853fb99306d7b

    1.命名规则

    本命名规范针对深度学习,根据我平时写代码的时候自己总结的一套规则。

    1.1 路径命名规则

    全部采用小写代码,使用名词,不适用动词。
    比如我自己的一个代码结构:

    ---- data: 数据集
    ---- models:模型
    ---- dataprocess:数据处理
    ---- logs:日志文件
    ---- utils:工具类
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.2 代码文件/类命名

    驼峰命名法则,开头大写,使用名字、动名词
    比如我自己一个代码命名

    ---- ModelingAbstrct:模型训练抽象类
    ---- DataSetLoader:数据集加载类
    ---- DataProcesser: 数据预处理类
    
    • 1
    • 2
    • 3

    1.3 函数/变量命名规则

    java使用驼峰命名法,首字母小写,动词加名词
    python使用蛇形命名法,全部使用小写字母,使用下划线做为分隔符
    比如我自己的一个代码命名:

    ---- def convert_word_to_token():将汉字转换成token
    ---- def load_origin_data():加载原始数据
    ---- best_micaroF1:最优微平均
    ---- max_doument_length:最大文本长度
    
    • 1
    • 2
    • 3
    • 4

    2.高可读命名规范

    2.1 为什么命名这么重要

    原因:

    • 第一眼被人看到,留下第一印象
    • 看不懂代码片段的时候,会结合命名进行联想
    • 获取某个范围中的关键信息时,会使用全局字符查找

    那么如何又能规范命名?

    • 变量名能否看出这个变量关联什么东西
    • 变量名是否能够看出变量是用来做什么的?

    举一个例子:
    给一段我们通常容易写的代码命名

    class File
    {
    int d;
    }
    bool flag=false;
    List<File>list1=new List<File>(....);
    foreach(var item in list1)
    	{
    	if(item.d>0){
    		flag=true;
    		break;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    看了这段代码是不是很熟悉,就像我们平时写的代码一样,代码中的变量没有人和语义信息,需要联系上下文才可以看出代码所表达的含义。

    ** 优化命名规范:**

    class File
    {
    int daysSinceModifycation;
    }
    
    bool isFileChanged=falseList<File>createFiles=new List<File>(...);
    foreach(var file in createdFiles){
    	if(file.daysSinceModification>0){
    		isFileChanged=true;
    		break;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这是优化后的代码,是不是感觉代码的可读性瞬间提高了?

    2.2 变量的命名规范

    2.2.1 整型变量命名

    举个小例子,我们需要命名一个整数的天数和时间,看看一般人是怎么命名的,然后大佬又是怎么命名的。

    int d; //菜鸡
    int days;// 正常
    
    //大佬的命名方式,将天数与用途全部写入命名中
    int elapsedTimeInDays;// 流逝的时间天数
    int daysSinceCreation;// 创建的时间天数
    int daysSinceModdification;//修改的时间天数
    int fileAgeInDays;// 文件存在时间天数
    
    //----------------------------------------
    int t;
    int times;
    
    int timesOfRequestRetry;//请求重复次数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    注意点:

    • 1.如果命名需要注释来补充,那其本身就不算名副其实
    • 2.明确计量对象(What)计量单位(Count,Time,Day,Minute,Second)

    2.2.2 布尔类型变量命名

    举个小例子

    boolean flag; // 我想表达进程是否已经完成
    boolean loaded; //我想表达页面是否加载完成
    
    //高级表达
    boolean isProcessFinished;
    boolean isPageLoaded;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    注意点:

    • 1.以正逻辑为主(个人习惯), 减少反逻辑带来的可读性影响
    • 2.前缀词(is,can,has,need) +名词+形容词/动词,让变量更直观

    2.2.3集合型变量命名

    通常我在遍历集合的时候,都是用item作为变量,如果有多个item的时候时候,就会混淆。
    举个例子:

    List<File>list1=new List<File>(....) // 创件一个file list
    foreach(var item in list){
    ........
    }
    
    
    //---------------规范表达--------------------
    List<File>createdFiles=new List<File>(.....);
    foreach(var file in createdFiles){
    ..........
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意点:

    • 1.对于自定义类型名,可以考虑作为变量名中的一部分
    • 2.加_上复数表示,可以让遍历操作的代码可读性更加直观

    最后对开始的案例进行一个规范的修改:

    2. 3变量命名容易出现名不副实的场景

    1.使用简单代码调试之后准备正式使用的时候
    注意:是否有测试时图方便而命名不规范的地方

    2.拷贝网上的代码用于项目中时
    注意:是否有需要调整命名的地方

    3.业务逻辑修改之后
    注意:是否有命名和现有逻辑不匹配的地方

    4.阅读自己或他人之前编写的代码的时候
    注意:是否有不符合规范的地方

    2.4 比较建议的重构原则

    • 定要全局修改所有引用处,避免存在全局变量的影响
    • 只要看到不规范的地方,就可以顺手修改,避免以后忘记
    • 每一处小小的优化都是对代码质量的提升

    3.对变量做有意义的区分

    如果程序员只是为满足编译器或解释器的需要而写代码,就会制造麻烦。
    例如:
    因为同一作用范围内东西不能重名,你可能会随手改掉其中一个名称,或干脆以错误的拼写充数。

    3.1 案例分析

    3.1.1 数字系列命名

    举个例子:

    public void copyChars(char a1[],char a2[]){
    	for(int i=0;i<a1.length;i++)
    		a2[i]=a1[i]
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    问题:
    依义命名成了依数命名,这样的名称纯属误导,没有提供正确信息,对可读性带来危害。
    后续如果还存在相近的变量,仍然存在命名冲突的烦恼。

    优化:

    public void copyChars(char sourceChars[],char destinationChars[]){
    	for(int i=0;i<a1.length;i++)
    		destinationChars[i]= sourceChars[i]
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用sourceChars/source和destinationChars/destination作为参数名。即清晰表示了变量本身的含义,又不容易有后续命名冲突上的烦恼。

    3.1.2 nonsense命名

    举个例子:

    class Product{
    	...
    }
    
    class ProductInfo{
    	....
    }
    
    class ProductdData{
    	....
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    问题:
    Info和Data本身意义含混,无论是否加上它们意义都基本没有区别。
    无法体现类之间的不同点,会让代码阅读者抓狂。

    优化:
    如果打算这样命名,先问自己:

    • 几个类之间具体的含义/功能区别是什么,是否有必要分成多个类?
    • 如果有必要区分,是否具有更清晰的命名? (通常一一定可以找到更有区别意义的命名)

    3.2 变量名容易出现无意义区分的场景

    1.多次修改代码后编译一直出现错误
    注意:耐心定位代码中的问题,切勿暴躁地随意修改。
    2.设计、编码的思考不够
    注意:命名时不仅要考虑本身的含义,还需要注意相近意义的区分。

    3.3 比较建议的重构原则

    1.研究清楚逻辑后再小心修改。
    代码中有相近命名时本身就容易混淆,理解代码逻辑后再修改可以避免重构后引发问题。
    2.代码是给程序员阅读和修改的,编码时应尽量从读者的角度去思考。

    4.避免误导命名

    程序员必须避免留下掩藏代码本意的错误线索。

    4.1 误导的来源:

    • 1.缩写/简写误导
    • 2.多义词汇误导
    • 3.变量类型误导
    • 4.外形相似误导

    4.2 案例分析

    4.2.1 缩写/简写误导一使用的缩写/简写只有自己认知

    //通用的简写/缩写
    // Get source position
    GetSrcPos();
    
    //Convert rgb to gray format
    Rgb2Gray();
    
    //可能只有自己才看的懂的
    // Set data's status
    SetDataSta()
    
    //Query user address
    QueryUserAdd();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    问题:

    • 1.使用的简写/缩写形式不一定每人都能理解,需要具体研究代码才明白。
    • 2.简写/缩写的结果不规范,出现同义词的情况。

    优化:

    //Set data's status
    SetDataStatus();
    //Query user address 
    QueryUserAddress()
    
    • 1
    • 2
    • 3
    • 4

    1.如果要用简写,就使用通用的/大众认可的。
    2.不确定是否能被理解的情况下尽量用全写,这样不会有问题。

    4.2.2 多义词汇误导——出现其他含义的联想

    原文举例: hp、aix、 sco不该用作变量名,因为都是Unix平台的专有名称。
    举个例子:

    //开始时间or持续时间
    public bool SetMonitorTime(){
    //Set something
    /Windows注册表or登记机关?
    public string QueryRegistryContent(){
    //Query something
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    问题:
    如果没有上下文语境的提示,会有双关含义。

    优化:

    public bool SetMonitorStartTime(){
    //Set something
    }
    class WindowsRegistry{
    	public string QueryRegistryContent(){
    	//Query something
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 1.添加对应上下文的语境,比如迁移到类中或者模块里,方便理解。
    • 2.更换/添加对应单词。

    4.2.3 变量类型误导——一某些命名会让人误解变量的类型

    举个例子:

    class Account{
    	......
    }
    Account[] accountList;
    
    • 1
    • 2
    • 3
    • 4

    问题:
    别用accountList来表示一组账号,除非它真的是List类型,List对于程序员有特殊意义。

    优化:

    class Account{
    	.....
    	Account[] accountGroup;
    	Account[] bunchOfAccounts;
    	Account[] accounts;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    删除类型名,用更清晰的命名替代(即便容器是List,也最好别用其命名)。

    4.2.4 外形相似误导一-两个命名过于相近/含有 易混淆字符

    举个例子:

    class XYZControllerForHandlingOfStrings{
    }
    class XYZControllerForStorageOfStrings{
    }
    	inta= 1;
    	if(O == 1){
    	a= O1;
    	else{
    	|= 01;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    问题:

    • 两个命名过于相似,阅读者看到后可能产生误会。
    • O,0,o以及i, 1这样的字符很相近,容易看错。

    优化:
    避免变量名过于相似(尤其是长变量名),避免使用易混淆字符。

    5.函数命名常见误区以及命名规则总结

    5.1 动词滥用问题

    注意:
    避免滥用通用单词

    问题:

    • 通用单词可以在很多场景下命名,但不能区分具体函数职责。
    • 当函数本身的实现途径不同时,难以从函数名得到足够的信息

    下面就列举几个例子

    5.1.1 万能的Get

    GetTotalAmount();
    
    • 1

    上述的函数名是表达什么呢?

    获取属性?
    获取本地存储内容?
    获取网络内容?
    获取数据库内容?
    获取计算后的内容?

    5.1.2 万能的Add

    AddCharacter();
    
    • 1

    上述函数名是想表达什么呢?

    添加到头部?
    添加到尾部?
    从中间插入字符?

    5.2 各类函数命名动词详细总结

    5.2.1 创建/销毁

    动词用途示例
    Create创建实例,常用于实例化方法和工厂方法的命名CreateInstance
    Initialize初始化实例的属性和设置,Initialize本身也可作为类方法用来初始化InitializeInstance,Initialize
    Load加载配置,根据配置创建内容LoadFromConfig
    Destroy销毁实例,常用语析构方法DestroyInstance
    Uninitialize清理实例的属性和设置,通常和Initialize对应UninitializeInstance,Uninitialize

    5.2.2 获取/设置

    动词用途示例
    Get常用于取属性的类方法命名,也可作为通用获取方法命名GetStartTime
    Fetch通过网络请求获取内容FetchAllUsers
    Calculate通过计算获取内容CalculateTotalAmount
    Read读取(多用于文件,配置等)ReadFile,ReadConfig
    Query查询QueryRemainingAmount
    Find查找(多用于数据库,集合等),和search相似FindOrder
    Receive接收(多用于文件,消息等)ReceiveNewMessage
    Pull拉取PullLastestSourceCode
    Set常用于设置属性的类方法命名,也可作为通用设置方法命名SetStartTime
    Write写入(文件/配置等)WriteFile,WriteConfig
    Put放入PutUserWithId
    Push存入,推送(通知)PushNotification

    5.2.3 更新

    动词用途示例
    Reset强调重置(标记,状态)ResetTimer
    Refresh用于命名刷新(多用于页面,缓存等)RefreshCurrentPage
    Update更新(多用于配置,状态等)UpdateUserSetting

    5.2.4 添加/移除

    动词用途示例
    Add用于通用添加方法命名AddNewStudent
    Append强调在尾部添加(追加)AppendCharacter
    Insert强调插入(可以在任意位置)InsertCharacter
    Delete表示删除,和Remove相近DeleteDirectory
    Remove表示移除,和Delete相近RemoveInvalidDeals

    5.2.5 启动/停止

    动词用途示例
    Open开启(多用于开启状态,打开文件等)OpenEnhanceMode
    Start开始(强调开始某个流程)StartPortListening
    Launch发动/启动(多用于启动程序,服务)LaunchAssistService
    Close关闭(多用于关闭状态,关闭文件等)CloseEnhanceMode
    Stop停止(强调流程的终止)StopPortListening
    Pause暂停(强调流程的暂停,有可能后续会继续开启)PausePageLoading
    Finish完成(强调流程的完成)FinishRequesting

    5.2.6 集合类型相关数据处理

    动词用途示例
    Filter过滤,筛选(强调按照某些条件)FilterByName
    Merge合并(有时会带上合并规则)MergeTwoConfig
    Concat拼接(直接在结尾添加)ConcatToArray
    Split分割SplitInput
    Deduplicate去重(去重完全相同的项)DeduplicateList
    Reverse颠倒,反向排列ReverseRecord
    Sort排序(有时会带上排序规则)SortDealsByAmount
    Fill填充(一般会进行覆盖)FillAmountList

    5.2.7 通用业务数据处理

    动词用途示例
    Parse解析(解析成某些格式,解析提取某些内容)ParseFromJson,ParseResult
    Analyse分析(不一定能通过简单的方式获取)AnalyseLocation
    Convert类型转换(通常用于从一个类型转换到另一种类型)ConvertToString
    Format格式化数据FormatToLocaleString
    Validate合法性/有效性的校验ValidateUserInputs
    Ensure期待值的校验EnsureUserAge
    Compose组成(一般由多项内容组成一个结果)ComposeMessage
    Encode编码(依赖约定的编码格式)EncodeUrl
    Decode解码(依赖约定的解码格式)DecodeUrl
    Encrypt数据加密(依赖约定的加密算法)EncryptContent
    Decrypt数据解密(依赖约定的解密算法)DecryptContent
    Backup备份(需要注意拷贝方式,避免误导)BackupUserSettings
    Restore恢复RestoreUserSettings
    Import导入(通常用于按照特定格式的文件转换)ImportFromFile
    Export导出(通常用于转换成特定格式的文件)ExportToFile
    Compress压缩(依赖约定的算法)CompressOversizedFile
    Decompress解压缩(依赖约定的算法)DecompressOversizedFile

  • 相关阅读:
    Spring Boot的魔法:构建高性能Java应用
    手把手教你在Windows下搭建Vue开发环境
    Java笔记二
    UNETR 论文精解
    Python学习精粹008:使用Visual Studio Code开发Python
    java连接kubernete
    YoloV5-SPD+TensorRT:基于YoloV5-SPD的小目标检测算法训练
    SVM 支持向量机算法(Support Vector Machine )【Python机器学习系列(十四)】
    [机器学习算法] 主成分分析
    含文档+PPT+源码等]精品基于Uniapp+SSM实现的记账app[包运行成功]计算机毕业设计Android项目源码
  • 原文地址:https://blog.csdn.net/qq_35653657/article/details/132643257