热消息:编程中最难的就是命名?这几招教你快速上手

1000万云上开发者,全栈云产品0元试用:点击 免费试用 ,即刻开启云上实践之旅!

本文通过案例的讲解强调了命名的重要性及养成良好的命名习惯一些建议。

作者 | 陈立(勤仁)


(资料图片)

来源 | 阿里开发者公众号

你可不能像给狗狗取名字那样给类、方法、变量命名。仅仅因为它很可爱或者听上去不错。

在写代码的时候,你要经常想着,那个最终维护你代码的人可能将是一个有暴力倾向的疯子,并且他还知道你住在哪里。

一、为什么命名很重要?

在项目中,从项目的创建到方法的实现,每一步都以命名为起点,我们需要给变量、方法、参数、类命名,这些名字出现在代码的每个角落,随处可见,混乱或错误的命名不仅让我们对代码难以理解,更糟糕的是,会误导我们的思维,导致对代码的理解完全错误。如果整个项目始终贯穿着好的命名,就能给阅读者一个神清气爽的开始,也能给阅读者一个好的指引。

要知道,代码的阅读次数远远多于编写的次数。请确保你所取的名字更侧重于阅读方便而不是编写方便。

二、为什么很难正确命名?

有人称编程中最难的事情就是命名。我同样深以为然,中国有句古话叫做万事开头难。抛开环境搭建,真正到了编码阶段第一件事就是命名,而最常见的一种情况,就是毫无目的、仅凭个人的喜好的去决定了一个名字。但因为没有想清楚目标和具体实施步骤,所以进行过程中往往会面临无数次的小重构甚至是推倒重来。

1、缺乏意愿

害怕在选择名字上花时间,对做好命名的意愿不足,随心所欲,甚至无视团队对命名的基本规范,觉得编译器能编译通过,代码能正常运行就成。

其实对发现的命名问题进行重构和推倒重来并不可怕,最可怕的是当下程序员不具备发现问题后肯回过头来纠偏的意愿。这终将演变成为一场灾难。

2、缺乏思考

没想清楚被命名的事物是什么,事物应该承担什么职责,是否会对其他人造成误解。

新手程序员总会花很多时间学习一门编程语言、代码语法、技术和工具。他们觉得如果掌握了这些东西,就能成为一个好程序员。然而事实并不是这样,事实上,编程不仅仅关乎掌握技能和工具,更重要的是在特定范畴内解决问题的能力,还有和其他程序员合作的能力。因此,能在代码中准确的表达自己的想法就变得异常重要,代码中最直观的表达方式是命名,其次是注释。

3、缺乏技巧

选一个好的名字真很难,你可能得有较高的描述能力和共同的文化背景。并且知晓一些常见且应该避免的命名问题。

如果最终还是没法找到合适的名字,还请添加准确的注释辅助他人理解,等想到合适的名字后再进行替换,不过往往能够通过注释(母语)描述清楚的事物,命名应该问题不大,问题大的是连注释都无法准确表达,那说明可能当前类、函数、变量承担的职责太多太杂。

三、如何正确的命名?

这里不讨论具体语言的命名规则,原因是不同编程语言命名规则各不相同,甚至不同团队间相同语言的命名规则也有出入。这里主要从提高可读性出发,结合我所在的客户端团队日常开发情况,以Java作为演示语言,给一些关于命名的建议。

1、名副其实

无论是变量、方法、或者类,在看到他名称的时候应该以及答复了所有的大问题,它应该告诉你,它为什么会存在,他做什么事,应该怎么做。如果在看到名称时,还需要去查找注释来确认自己的理解,那就不算名副其实。而且在发现有更好的命名时,记得果断替换。

Case1:到底怎样算End?

代码示例:

public interface OnRequestListener {/** * 请求结束 只有成功点才认为是真正的结束 * @param ... */void onRequestEnd(....);/** * 请求开始 * @param ... */void onRequestStart(...);}

大脑活动:

onRequestEnd是请求的什么阶段?请求成功和失败任一情况都算 “end”吗?喔,原来注释有写:“只有成功点才认为是真正的结束”。

修改建议:

// 省略注释public interface OnRequestListener {        void onStart(....);        void onSuccess(....);    void onFailure(...);}

2、避免误导

在每种语言中都有内置的标识符,他们都有特定的含义,如果和他们没有关联就不要在命名中加上他们。

2.1 避免使用令人误解的名字

Case1:命错名的集合

代码示例:

private ListdataSet;

大脑活动:

“dataSet” 在最初一定是为了元素去重选择了Set类型,肯定后来某一个历史时刻发现有bug被偷偷改成了List类型,但是变量名没变。

代码跟读:

跟踪提交记录,呃,在18年被刚定义时就是 List<***>dataSet;

修改建议:

private ListdataList;或者private Listsections;

Case2:不是View的View类

代码示例:

/** 作者+日期 */public class RItemOverlayView {}
/** 作者+日期 */public class NRItemOverlayView {}

大脑活动:

“N”是啥意思?类名只有一个N的字母差别,难道是新旧的差别,新的和旧的有什么区别呢?

类名以View结尾,嗯,应该是一个视图,可是,视图为啥不用继承视图基类的?

代码跟读:

喔,N确实代表“New”的意思,NRItemOverlayView被首页推荐使用,RItemOverlayView被购后推荐使用。

这个类主要核心工作是构建浮层视图(职责并不单一),而类本身并不是一个真正的视图;

修改建议:

// 放在首页推荐场景的包下public class ItemOverlayViewCreator {}
// 放在购后推荐场景的包下public class ItemOverlayViewCreator {}

Case3:整形变量为啥要用is开头

代码示例:

private int isFirstEnter = 0;

大脑活动:

为什么“is”开头的变量却声明成整形?到底是要计数还是判断真假呢?

代码跟读:

isFirstEnter < 1 做第一次进入的逻辑

修改建议:

private boolean isFirstEnter = true;

Case4:开关作用反掉啦

代码示例:

....if (InfoFlowOrangeConfig.getBooleanValue(POST_DELAYED_HIDE_COVER_VIEW_ENABLE, true)) {    hideCoverImageView();} else {    delayedHideCoverImageView();}

大脑活动:

为什么开关名为“delay....”为“true”的时候,走的不是delay逻辑,那开关要怎么发?容我多看几遍,是不是最近没休息好所以看岔了。

代码跟读:

反复看了几遍,确实是开关命名和实际操作完全相反,开关名意为“延迟隐藏封面视图”,执行的却是“立即隐藏封面视图”。

修改建议:

....if (InfoFlowOrangeConfig.getBooleanValue(IMMEDIATELY_HIDE_COVER_VIEW_ENABLE, true)) {    hideCoverImageView();} else {    delayedHideCoverImageView();}

剩余60%,完整内容请点击下方链接查看:

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

关键词:

推荐DIY文章
主机存在磨损或划痕风险 PICO4便携包宣布召回
穿越湖海!特斯拉Cybertruck电动皮卡可以当“船”用
vivoXFold+折叠旗舰开售 配备蔡司全焦段旗舰四摄
飞凡R7正式上市 全系标配换电架构
中兴Axon30S开售 拥有黑色蓝色两款配色
荣耀MagicBookV14 2022正式开售 搭载TOF传感器
it