写让人看得懂的代码

朋友发了段 js 代码给我问原理,我的回答很直白:
vZ5QRP.png

首先我确实不清楚执行结果为什么会是这样,也许涉及到了运算符的优先级及 js 下怪异的隐式类型转换,但这些都不重要,重要的是,这个代码有什么意义?

如果没有意义,而又觉得无趣,那也没有研究的必要了。

如果它是有意义的,而且是项目里某项重要逻辑的一部分,那它是否伴有清晰的注释解释其工作原理及这样写的必要性?

回到题目本身,在写代码时,我们需要经常反省:“我写的代码我的同事们能看懂么?”

这是我近两年多时间,经历数个十人以上参与维护的项目后反问自己的问题。

曾经,我也是下面这些写法的拥趸:

// 交换两数,结果 a: 15 b: 10
let a = 10
let b = 15
a ^= b
b ^= a
a ^= b

// 判断存在子串
if (~"hello".indexOf("h")) {
    // do something
}

// 交换 0 1
let a = 1;
// in some loop
{
    a ^= 1;
    console.log(a); // 0,1,0,1,0 ...
}

// 嵌套三目运算符或逻辑运算符
const a = condition1 ? 1 : condition2 ? 2 : 3;
const b = x || y && c && d || e;

// ...

但在看了其他人更多奇奇怪怪的「短小精悍」代码之后,我下定决心自己不再写这样的代码,而且在后面的 code review 中也坚决打回这类自以为是的写法,为什么呢?

代码是写给人看的

这话无论是对维护个人代码还是参与团队协作同样适用:
* 你是否被数月前甚至数星期前自己写的代码困扰过
* 你的同事是否经常跑来问你某个逻辑之前为什么要那样实现

所以,代码首先是写给人看的,其次才是给机器运行的,我们产出的代码,生命周期短则数月、长则数年,会被一批又一批人阅读、修改,如果净整些奇技淫巧,那公司、项目确实「离不开」你,而另一方面,别人也再难以与你展开合作了。

代码的意义应该不言自明

优秀的代码,应该是自说明的,也就是不需要注释也能明白其目的,举个最简单的例子,如下代码没写注释你一定能明白其意义:

let result;
if (isA()) {
    result = doSomthingA()
} else if (isB()) {
    result = doSomethingB() 
} else {
    result = doSomethingC()
}

而写成这样,代码行数确实变少了,但却很难一眼看明白了,而且极易改出 bug:

let result = isA() ? doSomthingA() : isB() ? doSomethingB() : doSomethingC()

追求代码以最小的行数实现在大部分情况下是无意义,毕竟我们不是在参加《一行代码可以做什么?》

做让人看得懂的架构

私以为,架构是用来做「约束」的。

如果设计的架构不能很好的约束参与开发项目的其他人,那至少应该不遗余力的主动推销自己的设计,让人遵循「设计约定」,如果他、她、Ta 都不遵守,那这个架构终会成为项目的负担。

为已有的架构引入新的特性也是同样的道理,首先要考虑的是解决什么问题,其次与再其次要考虑的都是它的理解心智是不是够低、使用成本是不是够低,过高的理解心智与使用成本,依然强按头让人家用,人家也不愿意用,结局与上例无异。

移除某架构特性的成本远高于移除某个 feature

结论

写代码不是:走自己的路让别人去说吧,或者走自己的路让别人无路可走。

软件工程,首先是工程,其次才是软件、是代码。软件工程少不了团队协作,避不开:
* 改别人的代码
* 别人改我的代码
* review 别人的代码
* 别人 review 我的代码
* …

高效的协作沟通就是尽可能“避免沟通”,用共同的语言:「编程语言」达成信息交换。