感谢公司的图书角,让我免费读到了这样一本好书。
用kindle已经有一段时间了,也陆陆续续地在上面买了一些电子书。但慢慢地发现,还是读纸质书来得舒服,翻起来也方便。当然,最好是自己买的书,可圈可点,不喜欢的书还可以拿来擦屁股。
然后我就联想到了李敖的读书秘诀,给大家摘一段体会一下:
我李敖看的书很少会忘掉,什么原因呢?方法好。什么方法?心狠手辣。剪刀美工刀全部用到,把书给分尸掉了,就是切开了。这一页我需要,这一段我需要,我把它按类别分开来。那背面有用怎么办呢?把它影印出来,或者一开始就买两本书,把两本书都切开以后整理出来,把要看的部分分类留存。结果一本书看完了,这本书也被分尸掉了。这就是我的看书方法。
虽然有点偏激,但至少说明,读书要活读,要跟书互动,产生参与感,还要温故知新,常翻常新。纸质书可以做到,电子书总归不那么方便。
《编写可读代码的艺术》,一个书名就已经道出了它接下来的目标了。谈到艺术,大多时候是从微小处着眼,细细体味,而非一个hello world那么简单。有生活,有哲学,代码也该像一件精心雕琢的艺术品。
这本书的结构已经非常清晰了,再做总结总显啰嗦。下面是我读这本书时想到的,并非笔记。
想人所想
这个标题看起来一点都不酷,但是做起来甚至会感动到我们自己。我们不想看到队友因为看不懂代码而苦恼的样子,我们的用户已经疲惫不堪,我们不想让他们再承受着蹩脚的使用体验。
写代码和写文章是极其类似的,作者要站在读者的角度思考问题。
读者读到这个词时是否会理解它,会不会产生歧义,是否需要了解某个背景,这段话是不是多余,会不会太啰嗦。
作者要思考比读者多得多的东西,因为作者这个角色本身,是包含了读者角色的双重角色。
站在再高一点,从系统用户的视角来看,这个字段的描述用户是否能看懂,是否正确理解了它的用途,有没有必要填写,用户是否可直观地了解有哪些注意事项,是否知道在做什么,当用户看到这个提示时是否知道它在说什么,blahblahblah一大坨,慢慢体会。
我们即是作者,又是读者;即是开发者,又是维护者;即是产品,又是用户。
遵循惯例
遵循惯例可以看作是“想人所想”的一部分。
每个行业都有自己的惯例。伴随着行业的发展,大家在相互配合中,整理出了一些行之有效的通用规则。
理想的情况是,这些通用规则,本行业的人,大家耳熟能详。
既然大家耳熟能详,就很少存在误解,也可能更好地被理解。这无疑对读者更友好。
当然,惯例也有可能带来相反的效果。《编写可读代码的艺术》里提到过一个例子,get_xxx()
按惯例来说就该是O(1)复杂度的函数,该书作者坚信这一点,结果该函数并非O(1)函数,导致作者在优化速度时吃了点苦头。
不过就像爱情一样,惯例是有的,你坚信,准没错,至少它能保证你在80%的情况下是正确的。这很值。
讲究卫生
一张干净的脸总是讨人喜欢的。
记得小时候家里不富裕,还穿过打补丁的裤子。老师教导我们,裤子破了打补丁很正常,但即使打了补丁,也要把裤子洗干净。一个漂亮的补丁,甚至会给一条旧裤子增色,就是这样。
在我的理解里,讲究卫生意味着整洁和干净。注意变量的出场顺序,把相关的代码或变量分块,都是一些好习惯。
好的代码就是要看上去赏心悦目。
可能有的人觉得,只要让系统运行起来就万事大吉了,很明显,这是不负责任。
我维护过一些系统,杂乱且无用的旧代码像战场上的残骸,任性的空格空行天马行空放荡不羁,拷贝的痕迹随处可见。这些都会加重读者的心理负担。
当然,我们也有能力写出这样的代码,所以,可以安静下来想想,怎么对待自己。
提升技能
书中提到一点我觉得很受用:偶尔地翻一下语言内置的和常用的第三方库。
维护代码需要很大成本,甚至我们的大部分时间都是在做维护的工作。以我之前做的“代码发布系统”为例,开发用了一个月,后期的维护已经达到8个月之久,而且还会持续下去。
而大部分第三方库都已经过严格测试,而且可以节约我们的维护成本。
有的程序员喜欢重造轮子,出于学习目的或现存库不能满足需求还好,如果是为技术而技术,可要在关键时刻提醒一下自己啰。
屏蔽细节
最后一点同样重要,帮助我们的读者隐藏不必要的细节。
函数的一个好处是,它把繁杂的上下文剥离开,让理解变得简单。比如,send_mail_html(mail_address, html)
这个函数可以给指定邮箱地址发送一段html类型的文本,只要函数封装地够好,用户或主调函数无需关心它的实现细节。
这也是自下而上编码的好处,上层提供了比下层更高一级的操作接口,并为用户屏蔽下层的实现细节。从这个意义上来说,编程语言也是自下而上中的一层实现,语言的细节我们无需关心,只要它封装地够好且使用无歧义。
再往大了说,一个好的团队也应该有屏蔽彼此细节的能力,团队中的成员由不同的领域专家组成,大家的职责彼此正交。这时,如果你是一个虚拟化技术的专家,而我更擅长用系统来为大家提供帮助,如果我的系统需要申请一个临时环境,调用你的一个接口,我可以获得一个可用的ip,你怎么生成这个环境我不关心,我怎么用你也不用关心。再这时,如果我们要改变容器的管理方式,这对我们的用户是透明的,也就是说,他们甚至都不知道我们在做这一操作,用户只需关心他们所应关心的内容即可。
函数的使用亦如是,彼此一体却又边界清晰。
总结
编码如是,生活亦如是。