当前位置: 首页 > news >正文

clean code阅读笔记——如何命名?

命名的原则

1. “小处诚实非小事“

有个词叫做”以小见大“。以建筑作喻,宏大建筑中最细小的部分,比如关不紧的门、未铺平的地板,甚至时凌乱的桌面,都会将整个大局的魅力毁灭殆尽,这就是整洁代码之所系。

2. 有意义的命名

选个好名字,省下来的时间比花掉的多。一旦发现有更好的名字,就换掉旧的名字。

2.1 名副其实

变量、函数和类的名字应该告诉读者:它为什么存在、它做什么事、它应该怎么用。如果名称需要注释来补充,那就不算是名副其实。

举例:

int d;	// 消逝的时间,以日计

上例中,变量d只能暗示这是一个表示day-天数的变量,但没有“消逝”的含义。我们应该明确指明计量对象和计量单位的名称:

int elapesdTimeInDays;
int daysSinceCreation;
int daysSinceModification;
int fileAgeInDays;

再举一个例子:

std::list<vector<int>> *getThem()
{auto *list1 = new std::list<vector<int>>;for (auto &x : theList){if (x[0] == 4)list1->push_back(x);}return list1;
}

上例中getThem、x[0] == 4、theList等,都比较模糊。可以改成这样:

list<vector<int>> *getFlaggedCells()
{auto *flaggedCells = new list<vector<int>>;for (auto &cell : gameBoard){if (cell[STATUS_VALUE] == FLAGGED)flaggedCells->push_back(cell);}return flaggedCells;
}

还可以更进一步,不用vector<int>来表示单元格,而是用一个对象来表示,并做好封装:

list<Cell> *getFlaggedCells()
{auto *flaggedCells = new list<Cell>;for (auto &cell : gameBoard){if (cell.isFlagged())flaggedCells->push_back(cell);}return flaggedCells;
}

与第一个版本比起来,这里明显更容易理解了。

2.2 避免误导

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

  • 避免使用特定平台专有名称。如hp、aix、sco。
  • 避免物理数据结构名称与变量名不同的情况。例如AccountList,其内部是用list存储的吗?
  • 避免使用不同之处较小的名称。
  • 避免l、o这种外观有歧义的名称。

2.3 做有意义的区分

对于编译器或者解释器来说,只要名称中有一个字符的不同就不会出错,但是对于读者来说,我们不仅需要名称不同,还要对名称做出有意义的区分。

举例来说,对于a1, a2, a3,…这样的区分方式,任何人不结合上下文的情况下看了都会一头雾水。还有类似getActiveChannel, getActiveChannels, getActiveChannelInfo这样的命名方式,也不容易看出它们的区别。

另外,我们也要尝试抛弃变量命中没有意义的部分,例如NameString,不如改为Name,除非Name还可以不用String来表示。

2.4 使用读的出来的名称

读的出来的名称一方面便于程序员间的交流,另一方面也利用了人类大脑的语言功能,便于理解和记忆。

比较下面两个例子:

class DtaRcrd102
{
private:Date genymdhms;Date modymdhms;const string pszqint = "102";
};
class Customer
{
private:Date generationTimestamp;Date modificationTimestamp;const string recordId = "102";
};

2.5 使用可搜索的名称

可搜索性还是在强调名称要具有区分度。所以坚持这个原则:长名称胜于短名称(除非短名称已足够精确),搜得到的名称胜于用自造编码代写的名称

单字母名称仅适用于短方法中的本地变量。名称长短应与其作用域大小相对应

2.6 避免使用编码

尽量避免将对象的类型和作用域编码进名称中,因为这会增加不必要的负担。现代的编译器和静态分析器能够帮助我们检查对象的类型。

看一下有哪些反例:

  • 匈牙利标记法(Hungarian Notation, HN)
  • 成员前缀m_

有一个例外是对接口和实现的编码,例如对于抽象工厂模式,可以将接口类命名为ShapeFactory,而将具体类命名为ShapeFactoryImpl。

2.7 避免思维映射

不应当让读者在脑中把你的名称翻译为他们熟知的名称。这种问题经常出现在选择是使用问题领域术语还是解决方案领域术语时。

我们应该尽量让名称明确,而不是自以为是的认为一种名称与某个对象之间存在一种映射关系。例如以r代表url。最终目的是编写让他人能轻易理解的代码。

2.8 类名

类名和对象名应该是名词或者名字短语,如Customer, WikiPage, Account和AddressParser。避免使用Manager, Processor, Data, Info这种缺少实际意义的词。类名不应当是动词。

2.9 方法名

方法名应当是动词或动词短语,如postPayment、deletePage或save。

重载构造器时,使用描述了参数的静态工厂方法名。例如,

Complex fulcrumPoint = Complex.FromRealNumber(23.0);

通常好于

Complex fulcrumPoint = new Complex(23.0);

2.10 别扮可爱

名字不要太耍宝,毕竟别人不一定有你的幽默感。宁可明确,毋为好玩。

2.11 每个概念对应一个词

给每个抽象概念一个词,并且一以贯之。例如不要混用fetch、retrieve和get。在同一堆代码中有controller,manager和driver,它们的区别是什么?

2.12 别用双关语

避免将同一单词用于不同目的。如果同一术语用于不同的概念,那么它基本上就是双关语了。

我们要遵循“一词一义”规则,例如对于add方法,如果它出现在多个类中,我们要保证这些add方法的参数和返回值在语义上等价。具体地说,如果在一个类中。add方法通过增加或连接两个现存值来获得新值并返回。现在要写一个新类,需要一个方法能够把参数添加道容器中,那么就不能把这个方法叫做add,因为这样做的话,add就变成了双关语。可以使用insert、append之类地词。

2.13 使用解决方案领域名称

我们的读者都是程序员,所以如果可以尽量使用计算机科学中的术语、算法名、模式名和数学术语。例如,对于熟悉访问者(VISITOR)模式的程序员来说,AccountVisitor富有意义。

2.14 使用源自所涉问题领域的名称

如果真的不能用程序员所熟悉的术语来命名,那就采用问题涉及领域的名称吧。至少,负责维护代码的程序员知道该去请教谁。

优秀的程序员和设计师,其工作之一就是分离解决方案领域和问题领域的概念。与所涉问题更为贴近的代码,应当采用源自问题领域的名称。

2.15 添加有意义的语境

单单一个名称能够说明的信息还是太过有限。我们需要有良好命名的类、函数或者名称空间来放置名称,给读者提供语境。如果没有这么做,那么给名称添加前缀就是最后一招了。

那么如何添加语境呢?举例来说,可以从一个复杂的函数体中拆分出多个步骤,然后给这些子函数命上合适的名字,从而提供更多语境,告诉读者整个函数的逻辑。

不要添加没用的语境

只要现有的代码已经足够清楚,就没必要拆分出不同的子函数。只要短名称足够清楚,就比长名称好。

相关文章:

clean code阅读笔记——如何命名?

命名的原则 1. “小处诚实非小事“ 有个词叫做”以小见大“。以建筑作喻&#xff0c;宏大建筑中最细小的部分&#xff0c;比如关不紧的门、未铺平的地板&#xff0c;甚至时凌乱的桌面&#xff0c;都会将整个大局的魅力毁灭殆尽&#xff0c;这就是整洁代码之所系。 2. 有意义…...

MacOS 如何解决无法打开 ‘xxx’,因为 Apple 无法检查其是否包含恶意软件

背景 在安装软件时&#xff0c;遇到“无法打开 ‘xxx’&#xff0c;因为 Apple 无法检查其是否包含恶意软件” 的提示&#xff0c;许多用户可能会感到困惑&#xff0c;不知道该如何处理。遇到这个问题时&#xff0c;按以下步骤操作即可解决。 首先&#xff0c;这个警告提示的出…...

Java并发学习:进程与线程的区别

进程的基本原理 一个进程是一个程序的一次启动和执行&#xff0c;是操作系统程序装入内存&#xff0c;给程序分配必要的系统资源&#xff0c;并且开始运行程序的指令。 同一个程序可以多次启动&#xff0c;对应多个进程&#xff0c;例如同一个浏览器打开多次。 一个进程由程…...

省市区三级联动

引言 在网页中&#xff0c;经常会遇到需要用户选择地区的场景&#xff0c;如注册表单、地址填写等。为了提供更好的用户体验&#xff0c;我们可以实现一个三级联动的地区选择器&#xff0c;让用户依次选择省份、城市和地区。 效果展示&#xff1a; 只有先选择省份后才可以选择…...

springboot 动态配置定时任务

要在Spring Boot中动态配置定时任务&#xff0c;可以使用ScheduledTaskRegistrar类来实现。 首先&#xff0c;创建一个定时任务类&#xff0c;该类需要实现Runnable接口。例如&#xff1a; Component public class MyTask implements Runnable {Overridepublic void run() {/…...

数据结构与算法学习笔记----求组合数

数据结构与算法学习笔记----求组合数 author: 明月清了个风 first publish time: 2025.1.27 ps⭐️一组求组合数的模版题&#xff0c;因为数据范围的不同要用不同的方法进行求解&#xff0c;涉及了很多之前的东西快速幂&#xff0c;逆元&#xff0c;质数&#xff0c;高精度等…...

Arouter详解・常见面试题

前言&#xff1a;ARouter是一个用于 Android App 进行组件化改造的路由框架 —— 支持模块间的路由、通信、解耦。 一、路由简介&#xff1a; 路由&#xff1a;就是通过互联的网络把信息从源地址传输到目的地址的活动。完成路由这个操作的实体设备就是 路由器&#xff08;Rout…...

全志开发板 视频输入框架

笔记来源于百问网出品的教程。 1.VIN camera驱动框架 • 使用过程中可简单的看成是vin 模块 device 模块af driver flash 控制模块的方式&#xff1b; • vin.c 是驱动的主要功能实现&#xff0c;包括注册/注销、参数读取、与v4l2 上层接口、与各device 的下层接口、中断处…...

寒假学web--day10

简介 一些高级的反序列化 phar反序列化 phar类似于java的jar包&#xff0c;将多个php文件合并为独立的压缩包&#xff0c;不用解压就能执行里面的php文件&#xff0c;支持web服务器和命令行 metadata $phar->setmetadata($h); metadata可以存放一个类实例&#xff0c;…...

【全栈】SprintBoot+vue3迷你商城(9)

【全栈】SprintBootvue3迷你商城&#xff08;9&#xff09; 往期的文章都在这里啦&#xff0c;大家有兴趣可以看一下 后端部分&#xff1a; 【全栈】SprintBootvue3迷你商城&#xff08;1&#xff09; 【全栈】SprintBootvue3迷你商城&#xff08;2&#xff09; 【全栈】Spr…...

系统思考—问题分析

很多中小企业都在面对转型的难题&#xff1a;市场变化快&#xff0c;资源有限&#xff0c;团队协作不畅……这些问题似乎总是困扰着我们。就像最近和一位企业主交流时&#xff0c;他提到&#xff1a;“我们团队每天都很忙&#xff0c;但效率始终没见提升&#xff0c;感觉像是在…...

系统架构设计师教材:信息系统及信息安全

信息系统 信息系统的5个基本功能&#xff1a;输入、存储、处理、输出和控制。信息系统的生命周期分为4个阶段&#xff0c;即产生阶段、开发阶段、运行阶段和消亡阶段。 信息系统建设原则 1. 高层管理人员介入原则&#xff1a;只有高层管理人员才能知道企业究竟需要什么样的信…...

美国三种主要的个人数据产业模式简析

文章目录 前言一、个人征信(Credit Reporting)模式1、定义:2、特点:数据来源:核心功能:服务对象:代表性公司:监管框架:示例应用:二、面向垂直场景的个人数据公司(Consumer Reporting,消费者报告模式)1、定义:2、特点:数据来源:核心功能:服务对象:主要公司:监…...

js手撕 | 使用css画一个三角形 使用js修改元素样式 驼峰格式与“-”格式相互转化

1.使用css画一个三角形 借助 border 实现&#xff0c;在 width 和 height 都为 0 时&#xff0c;设置 border&#xff0c;便会呈现三角形。想要哪个方向的三角形&#xff0c;设置其他三边为 透明即可。同时&#xff0c;可以通过调整不同边的宽度&#xff0c;来调整三角形的高度…...

每日一道算法题

题目&#xff1a;最长递增子序列的个数 给定一个未排序的整数数组&#xff0c;找到最长递增子序列的个数。 示例 1 输入&#xff1a;nums [1,3,5,4,7]输出&#xff1a;2解释&#xff1a;有两个最长递增子序列&#xff0c;分别是 [1,3,4,7] 和 [1,3,5,7] 。 示例 2 输入&a…...

低代码系统-产品架构案例介绍、明道云(十一)

明道云HAP-超级应用平台(Hyper Application Platform)&#xff0c;其实就是企业级应用平台&#xff0c;跟微搭类似。 通过自设计底层架构&#xff0c;兼容各种平台&#xff0c;使用低代码做到应用搭建、应用运维。 企业级应用平台最大的特点就是隐藏在冰山下的功能很深&#xf…...

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(三)

Understanding Diffusion Models: A Unified Perspective&#xff08;三&#xff09; 文章概括 文章概括 引用&#xff1a; article{luo2022understanding,title{Understanding diffusion models: A unified perspective},author{Luo, Calvin},journal{arXiv preprint arXiv:…...

利用机器学习创建基于位置的推荐程序

推荐系统被广泛应用于不同的应用程序中&#xff0c;用于预测用户对产品或服务的偏好或评价。在过去的几分钟或几小时里&#xff0c;你很可能在网上遇到过或与某种类型的推荐系统进行过互动。这些推荐系统有不同的类型&#xff0c;其中最突出的包括基于内容的过滤和协作过滤。在…...

每日一题 429. N 叉树的层序遍历

429. N 叉树的层序遍历 /*class Solution { public:vector<vector<int>> levelOrder(Node* root) {queue<Node*> que;que.push(root);vector<vector<int>> ans;if(root nullptr){return ans;}while(!que.empty()){int sizeQue que.size();vec…...

AIP-132 标准方法:List

编号132原文链接AIP-132: Standard methods: List状态批准创建日期2019-01-21更新日期2022-06-02 在许多API中&#xff0c;通常会向集合URI&#xff08;例如 /v1/publishers/1/books &#xff09;发出GET请求&#xff0c;获取集合中资源的列表。 面向资源设计&#xff08;AIP…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...