编程之道

所有内容选自 王垠

那么提高程序正确性最有效的方法是什么呢?在我看来,最有效的方法莫过于对代码反复琢磨推敲,让它变得简单,直观,直到你一眼就可以看得出它不可能有问题。

代码的“抽象”和它的“可读性”(直观性),其实是一对矛盾的关系。适度的抽象和避免重复是有好处的,它甚至可以提高代码的可读性,然而如果你尽“一切可能”从代码里提取模板,甚至把一些微不足道的“共同点”也提出来进行“共享”,它就开始有害了。

这就是为什么我喜欢一种懒懒的,笨笨的感觉。因为我懒,所以我不会过早的思考代码的重用。我会等到事实证明重用一定会带来好处的时候,才会开始提取模板,进行抽象。经验告诉我,每一次积极地寻找抽象,最后的结果都是制造一些不必要的模板,搞得自己的代码自己都看不懂。很多人过度强调DRY,强调代码的“重用”,随时随地想着抽象,结果被这些抽象搅混了头脑,bug百出,寸步难行。如果你不能写出“可用”(usable)的代码,又何谈“可重用”(reusable)的代码呢?

很多人写程序的时候连“眼前特例”都没做好,就在开始“展望将来”。

如果在第一次的设计中就过早的考虑到将来,由此带来的多余的复杂性,有可能让初期的设计就出现问题。

如果你设计了框架性的代码,每个程序员为了在这个框架下编写代码,都需要理解这种框架的构造,这带来了学习的开销。一旦发现这框架有设计问题,依赖于它的代码很有可能需要修改,这又带来了修改的开销。所以加入“通用性”之后,其实带来了更多的工作。这种开销能不能得到回报,依赖于以上的多种因素。

很多人对 IDE 有偏见,因为他们认为这些工具让编程变得“傻瓜化”了,他们觉得写程序就是应该“困难”,所以他们眼看着免费的 IDE 也不试一下。

“看一个作家的水平,不是看他发表了多少文字,而要看他的废纸篓里扔掉了多少。” 我觉得同样的理论适用于编程。好的程序员,他们删掉的代码,比留下来的还要多很多。

如果我们忽略具体的内容,从大体结构上来看,优雅的代码看起来就像是一些整整齐齐,套在一起的盒子。如果跟整理房间做一个类比,就很容易理解。如果你把所有物品都丢在一个很大的抽屉里,那么它们就会全都混在一起。你就很难整理,很难迅速的找到需要的东西。但是如果你在抽屉里再放几个小盒子,把物品分门别类放进去,那么它们就不会到处乱跑,你就可以比较容易的找到和管理它们。

优雅的代码的另一个特征是,它的逻辑大体上看起来,是枝丫分明的树状结构(tree)。这是因为程序所做的几乎一切事情,都是信息的传递和分支。你可以把代码看成是一个电路,电流经过导线,分流或者汇合。

编程真的是一门艺术,它完全符合艺术的各种特征,编程界也充满了艺术界的独有特征。有些初学艺术的人(比如10年前的我),总是挑剔手上的工具,非要用最新最炫的工具,用它们最偏僻最难用的“特性”,才觉得自己能够做出优秀的作品。很多人照不出好的照片,就怪相机不好。买了几万块钱的笨重高档相机,照出来的照片还不如别人用手机照的。这些人不明白,好的摄影师和不好的摄影师,区别在于眼睛,而不是相机。一个真正的艺术家,可以用任何在手上的工具创造出色的作品。有些甚至可以用一些废品垃圾,拙劣的工具,做出杰出的,别具风味的艺术品。因为艺术存在于人的心里,而不在他们使用的工具里面。