[译]程序员要懂得“大道至简”
作者在Twitter上发的一条短讯:
“你永远都有简化的空间。”
11:29 AM – 2012-5-21
Rich Skrenta在“Code is our enemy”(代码是我们的敌人)一文中是这么说的:
代码不是什么好东西。代码会随着时间的推移慢慢腐烂。代码需要周期性的维护。代码里还藏有bug。新增功能意味着旧的代码需要被修改。你的代码越多,bug能藏身的地方就越多,迁出(check out)或者编译的时间也就越长,新员工理解你的系统所需要的时间也就越长。如果你不得不进行代码重构,那么你需要调整的地方还有更多。
代码是工程师制造出来的。如果要写更多的代码,那就需要更多的工程师。众多工程师之间有n 2的沟通成本。他们在扩展功能时加进系统的所有代码,也将增加整个系统的成本。你应该尽一切可能去提高每个程序员在代码表现力方面的能力,以使用更少的代码来完成同样的事情(甚至可能做得更好)。你雇用的程序员越少,组织沟通成本也就越低。
Rich在这里给出了一些线索,但是真正的问题不在代码。代码就像一个新生婴儿,在被带到这个世界来的时候,它是无辜而无可非议的。代码不是我们的敌人。你想看看真正的敌人吗?去照一照镜子吧。那里就是“你”的问题。就在那里!
作为一个软件开发者,你就是你自己最大的敌人。你越早认识到这点,你的境况就会越好。
我知道你抱有极大的善意。大家都一样。我们是软件开发者;我们热爱编码。那就是我们每天的工作。给我们一些强力胶带、一个简易衣架,再加上一小撮代码,我们总能解决任何问题。但是,Will Shipley却认为,我们应该控制住这种写上一大堆代码的自然倾向:
作为程序员,我们的任务是要意识到,我们所做的每个决定都是一个折中——这就是编码的本质。要想成为程序设计大师,那就要理解这些折中的本质,并且在我们编写的任何代码中都善加处置。
在编码过程中,你可以从很多维度去评价你的代码:
- 代码简洁度
- 功能的完整性
- 执行速度
- 编码所花费的时间
- 健壮性
- 灵活性
记住,这些维度相互之间都是对立的。你可以花上3天时间写一个非常美观而迅捷的程序,这样你在两个维度上获得了提高,但是因为你花了3天的时间,所以在“编码所花费的时间”这个维度上就落后了很多。
那么,在什么时候这样做才是值得的呢?我们该如何做这些决定呢?其实,答案非常合乎情理,也很简单,但就是从来没有人好好遵从:从简洁开始,然后依据测试的结果按需提升其他的维度。
对此我非常赞同!我曾在“ Code Smaller”一文中劝诫开发者们编写更小的代码。我给出的建议其实异曲同工。但不要走极端!我并不想挑起一场“reductio ad absurdum”竞赛:我们用尽书上所有的聪明技巧,让代码能够塞进更小的物理空间。 我想要的是一个实用而明智的策略,以缩减一个程序员在想要了解程序的工作原理时所须阅读的代码量。我这里有个很小的例子,以进一步说明我想表达的意思:
译者注:reductioad absurdum意指反证法,是拉丁语中的“转化为不可能”。反证法(又称归谬法、背理法)是一种论证方式,它首先假设某命题不成立(即在原命题的条件下,结论不成立),然后推理出明显矛盾的结果,从而下结论说原假设不成立,原命题得证。
if(s==String.Empty)
if(s==””)
对我而言,后面的那个显然更好一些,因为它更为简洁。然而,我几乎可以断定,一定会有开发人员跳出来与我争辩,可能还要“血战到底”,因为他们深信这个啰嗦的String.Empty对编译器来说更为友好(真是莫名其妙!)。说得我好像在乎这个一样。好像真有人在乎这个一样!
对于绝大多数软件开发者而言,承认这个事实是很痛苦的,因为他们是那么地热爱代码。但是,最好的代码就是完全没有代码(所谓“大道至简”)。每一行你欣然带到这个世界来的新代码都需要被调试,需要被其他开发者阅读和理解,并且被维护和支持。每当你需要新写代码的时候,你都应该很不情愿、但又迫不得已,因为你已经证明其他所有的方法都无济于事。之所以有人说“代码是我们的敌人”,正是因为我们当中的很多程序员写了太多太多的糟糕代码。然而,如果你不得不写代码,你也须 从简洁开始。
如果你热爱编码——而且爱得情真意切——那你就应该惜墨如金。