山地人

第007期.如何才能写出一手整洁的好代码?(中篇)

山地人
山地人
2021-05-13

Computer C++ Code

上期我们聊到了如何起一个好名字,这次我们接着来说起名。不过这次要聊的是起名时,应该避免的问题。

起名时,不应该做的那些事

一、避免使用编码

//在老的C/C++里有人喜欢用m_的前缀来表示成员变量
var m_name;
var m_age;
//变量中添加了类型信息
var phoneString;
var ageNumber;

前端里现在用m_的应该不多,可能有些小伙伴喜欢在变量中加入一些类型的信息。这个其实没有必要。如果你的类和函数足够小,那这些用来表明成员类型的m_前缀和变量名后面加的Number,String类型信息是挺多余的。代码看着也比较累赘,所以这些额外的编码信息就不要添加了。

二、避免思维映射

如果传统习惯中已经有的一些固有习惯,我们应该准守固有的习惯。比如我们平时用的循环计数器,通常会使用 i,j,k这几个单一字母来作为循环时的计数变量。

for(let i=0;i<total;i++){
...
}

当然这里要避免使用l,因为小写的l和数字1比较相近,容易出错。当然其他时候就不应该使用单一字母来起名了。

/**
** 避免下面的写法,这里的l和1的是不是在阅读的时候有辨认压力
**/
for(let l=1;l=10;l++){
...
}

比如你如果使用a,b,c来命名,那么在阅读你的这种代码的时候,阅读者还要在大脑中把你的这些a,b,c和实际的概念相映射,无形中增加了阅读代码的人的负担,因此应该避免

//只看前面的变量名j,你能知道j是干嘛吗?
let j = totalScore / count;
//如果换成下面的变量名呢,是不是代码的可读性增强了?
let avgScore = totalScore / count;

程序员都比较聪明,那么怎么区分一个程序员是聪明的程序员还是专业的程序员,这里有一条简单的判断依据,专业的程序员明白,明确是王道的道理。专业程序员会花很多精力在编写让其他人能够理解的代码上。

三、避免歧义

如果你在起名是遇到可能会带来误导含义的单词时,这时你最好换一个别的单词。始终保持你起的名字含义明确没有歧义,这样也是在提升你的代码的可读性。

上面我们聊了很多关于起名的推荐和应当避免的做法,现在我们再回头来看看我们的函数。解决好了起名问题,我们就可以好好来看看天天要打交道的函数function了。接下来,我们就来讨论下,如何让函数变得易读和易于理解的一些规则。

如何增强函数的可读性

一、短小

函数应该足够小,避免写出长的像拉面一样的代码。这里有两条规则,你应该去准守:

  1. 让函数足够小
  2. 如果函数已经小了,能否让他变得更小
function handleRegister() {
if (!RegUtil.isMatchPhoneNumber(this.userPhone)) {
Toast({
message: "请输入正确的手机号!",
position: "top",
duration: 1000,
className: "red"
});
} else {
const TIME_COUNT = 60;
if (!this.timer) {
Util.ajax
.post("/api/register/sms", { phone: this.userPhone })
.then(res => {
if (res.data.status === 200) {
this.count = TIME_COUNT;
this.show = false;
let that = this;
this.timer = setInterval(() => {
if (that.count > 0 && that.count <= TIME_COUNT) {
that.count--;
} else {
that.show = true;
clearInterval(that.timer);
that.timer = null;
}
}, 1000);
}
if (res.data.status !== 200) {
this.show = true;
Toast({
message: res.data.message,
position: "top",
duration: 1000,
className: "red"
});
}
});
}
}
}

请花2分钟时间阅读上面的这些代码,读完在心里想想你的感受。如果你平时就是这样来写代码的话,那那这一节的内容你需要好好消化吸收,下面是经过调整后的一段代码。

const TIME_COUNT = 60;
function showToast(msg) {
Toast({
message: msg,
position: "top",
duration: 1000,
className: "red"
});
}
function stopVerificationCodeTimer() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
}
function startVerificationCodeTimer() {
stopVerificationCodeTimer();
this.count = TIME_COUNT;
this.show = false;
this.timer = setInterval(() => {
if (this.count > 0 && this.count <= TIME_COUNT) {
this.count--;
} else {
this.show = true;
this.stopVerificationCodeTimer();
}
}, 1000);
}
function isVerificationCodeTimerRunning() {
return this.count > 0;
}
function fetchRegisterSMS(phone) {
return Util.ajax.post("/api/register/sms", { phone: this.userPhone });
}
function handleRegister() {
if (!RegUtil.isMatchPhoneNumber(this.userPhone)) {
showToast("请输入正确的手机号!");
} else {
if (!isVerificationCodeTimerRunning()) {
fetchRegisterSMS(this.userPhone).then(res => {
if (res.data.status === 200) {
startVerificationCodeTimer();
} else {
this.show = true;
showToast(res.data.message);
}
});
}
}
}

我把上面的业务代码进行了重新的拆分,按照函数应该尽可能小的原则进行拆分。经过一轮重构后,虽然现在的代码看上去比之前的版本要长一些,但是代码的可读性增强了。对比一下,同样的代码逻辑,你更愿意去读哪个版本的?

函数好了之后,会带来很多好处。首先单个函数的功能不会非常复杂,因为它足够小。另外,还可以让函数变得清晰,维护性也就增强了。试想,你在遇到一个函数时,你是更愿意去看一个长度为300行的函数还是更愿意去阅读一个长度不到5行的简短的函数呢?

二、只做一件事

每个函数应该只做一件事,并专注把这件事做好。

这里我们有必要了解一下软件设计上的一个SRP(Single Responsibility Principle)单一原则

三、函数参数不要超过3个

对于函数的参数数量,建议不要超过3个

如果函数能做到没有参数最好,其次是带有一个参数,再次是带有两个参数,如果参数达到3个已经是上限了。没有非常充足的理由你的函数参数不应该超过3个。

如果你的参数很多,那你就得考虑下如何重构你的代码了。你想在阅读代码的时候,参数数量越少阅读也更容易。没有参数的时候,你的函数名字起得到位,一看函数名你就能知道函数所表达的含义。如果函数带了一个参数,你要看函数名,并搞明白这个参数的含义才能理解这个函数。如果函数参数太多,你得花多少力气去搞明白每个参数的含义。

这是不是无形之中增加了代码的阅读难度,代码的可读性也就随之下降了。

四、不要让你的代码重复(DRY——Don’t Repeat Yourself)

很多新入行的开发者喜欢复制,粘贴代码。觉得这样很快很省事。殊不知你这么做,给自己挖了多大的坑。比如一段相同的逻辑,可能代码行数不多就5行。你写好一处后,换了一个地方,发现又是一段相同的逻辑,然后你回到之前写过的地方Ctrl+C,然后到新的地方Ctrl+V。就这样不一会儿,你就在4、5个地方使用了这样的操作。过了几天,来了一个新的需求,方式这样的功能的地方,统统要加一段验证进去。这下好了,因为你之前的拷贝粘贴的功劳。你得整个项目搜索出这5处地方,然后一处一处改代码。因为是手工操作,有时候,你还会漏改或者改错地方。你干的好辛苦

其实如果你当时在第二次遇到相同逻辑的时候,你把之前那段代码提前封装成一个函数。那你之后的调整,你只要在这个函数上做一次调整就搞定了5个地方的问题。所以做开发,该偷懒的地方要学会偷懒,不该偷懒的地方千万别偷懒。

五、使用带描述性的函数名

这个在上一篇的如何起名里已经讲了很多,这里就不赘述。

如果你准守了上面的这些规则,我相信不管是你的函数的可读性,还是理解的容易程度都会提升,慢慢得你就可以组织处优雅的会讲故事的系统了。

好的,这一期的《如何才能写出一手整洁的好代码?》我们就聊到这里。下一期我们再来剩下的一些写好代码的话题。