| ||||
| 今天碰巧看了2008年10月号的《程序员》杂志,全文登了《代码如散文》的翻译。 我查了查去年冬天的blog: beautiful code第20章和第29章翻译 - cpper编程论坛 看来书稿没有采用我的翻译。基本上是瞎忙了一把。我再把自己的翻译贴一下: 29. 代码如文 松本行弘(Yukihiro Matsumoto )1 程序和散文有不少相似之处,读者在阅读文章的时候,最重要的一个问题就是:“它是关于什么的?”对于程序,最主要的问题是:“它是做什么的?”实际上,作者的目的应该足够清晰,而这两个问题也根本就不应成为问题。然而,不论是文章还是代码,了解它们是如何写的也非常重要。尽管有些情况下,作者想要表达的思想很好,但是如果他写出的东西读者看不懂,就成了“茶壶里煮饺子,有嘴道(倒)不出”,作者的思想也就无从传播给读者。因此,观点和目的固然重要,文风和代码风格也同样重要。文章和代码的最终目的都是写给他人去阅读和理解的。[*] [*] 本章由Nevin Tompson从日文翻译为英文。 你也许会问:“计算机程序真的是写给人阅读的么?”通常的观点是,人们写程序告诉计算机如何做,然后计算机利用编译器或解释器编译并理解代码。最终,程序被翻译成只有CPU才理解的机器语言。这一观点无疑正确地描述了整个过程的工作方式,但是这一观点仅仅解释了计算机程序的一个方面。 绝大多数程序并非一次写成。它们在使用过程中被不断的重用和改进。错误必须被解决,需求的变更和功能的增加意味着程序本身也许会产生翻天覆地的变化。在这个过程中,人们必须能够读懂程序原来是到底是干什么的。从这个意义上说,写出人能够看懂的程序比写出计算机能够看懂的程序更重要。 虽然计算机能够毫无怨言地对付复杂的代码,人却无法做到这一点。难以阅读的代码将极大程度地降低人们的生产率。而容易理解的代码则会提高人们的生产率。并且我们会发现这些容易理解的代码的通常很优美。 “是什么使得计算机程序容易理解?”或者说:“什么是优美的代码?”虽然不同人对于什么是优美程序有不同的标准,但是判断计算机代码的质量却不是简单的审美问题,代码的质量直接影响到程序完成任务的好坏。也就是说,“优美的代码”并不是什么虚无飘渺的抽象的东西,而是和程序员的努力紧密联系在一起的。优美的代码的确能够使程序员感到舒服并且能够提高效率。这就是我用来衡量程序是否优美的标准。 简短是的代码优美的特性之一。Paul Graham2说:"简洁就是力量。"在编程领域,简短是一个褒义词。因为它明显会节省人们浏览代码的气力,完美的程序应该不包含任何冗余信息。 例如,为了简短,当没有必要声明类型,或者根本不需要使用类或主函数的情况下,就应该把它们全部去掉。例子29-1展示了这一原则,它们分别是Java和Ruby的Hello Word程序。 例 29-1. Java版"Hello World"和Ruby版的"Hello World"对比 Java Ruby class Sample {} public static void main(String[] argv) { System.out.println("Hello World"); } print "Hello Worldn" 两个程序都完成相同的任务——简单地显示出“Hello World”——但是Java和Ruby的方法却大相径庭。在Ruby的实现中,所有的一切仅仅是描述基本任务:打印"Hello Word"。没有声明,没有数据类型。在Java中,却不得不包含进来许多和我们最终目的无关的各种东西。当然Java这种将所有内容包含进来的方法也有它的好处。但是由于它无法省略任何这些东西,简短的特性就丧失了。(再深入一些,Ruby的Hello Word实际上是三语通用,在Perl与Ptython中也行得通。) 简短还意味着削除冗余。冗余是一种重复信息。当信息重复时,同时维护它们并保持一致的代价就非常高。因为大量的时间被投入到这种维护工作中,所以冗余会降低编程效率。 尽管有些不同的意见认为冗余可以帮助理解程序的意思,实际的情况却完全相反,因为冗余代码包含了太多过剩的信息。这样“肥胖”的代码造成了工具依赖症。虽然现在依赖IDE来编程日益流行,但是这些工具并不能帮助人们理解程序的意思。真正能够写出优雅代码的窍门是选择一门优雅的语言。Ruby以及其他类似的轻量级语言能够帮助做到这一点。为了消除冗余,我们可以遵守DRY原则:不要重复你自己(Don't Repeat Yourself)。如果同样的代码在许多地方出现,你所想要表达的东西就会变得晦涩难懂。 DRY原则的反面是“复制-粘贴”式编程,某些公司使用代码行数来衡量程序员的生产率,这实际上是暗中鼓励制造冗余。我甚至听到一种说法认为,有时尽量多地复制代码是一种美德。但这是不正确的。 我相信真正的美德存在于简洁。最近Ruby On Rails的流行就是因为它不懈地追求简洁和DRY原则。Ruby语言非常认真地贯彻“绝不重复同样的代码两次”和“简练地描述”原则。Rails从Ruby那里继承了这一哲学。 优美代码让人看起来感到熟悉,这一点可能争议颇多——人类的保守程度其实超过你的想像——大多数人很难接受新的概念或改变他们的想法。相反,很多人宁愿忍受也不愿去改变。如果没有好的理由,大多数人不愿意换掉他们习惯的工具或者学习一门新的语言。他们会不断比较需要学习的新事物和他们以前习以为常的老观念。并且通常不公正地针对新事物做出负面评价。 改变人们思维方式的代价之高远远超过了一般人的估计。为了从一种观念转换到另一种观念(例如,从过程式编程转换到逻辑编程或函数式编程3),他必须通晓大量的知识。人类的大脑对陡峭的学习曲线会感到痛苦。因此这会降低程序员的生产率。 从某种角度来说,由于支持“优美代码”的这一特性,Ruby是一门极为保守的编程语言。虽然Ruby是所谓的“纯面向对象”语言,但是它并不像Smalltalk那样使用基于对象消息传递的先进控制结构。相反,Ruby坚持使用程序员们熟悉的传统控制结构如,if, while等。甚至Ruby还从古老的Algo-系语言中借鉴来了end关键字。 与其他同时代的语言相比,Ruby有时看起来老气守旧。但是“不要太时髦”也是优雅代码的一个关键。 朴素是优美代码的另一特性。我们通常在简单的代码中看到美。如果一段程序难以理解,它就难以被认为优美。并且当代码晦涩难懂时,bug,错误,混乱就接踵而至了。 朴素是编程中被误解最多的概念之一。设计程序语言的人通常都希望保持语言的简洁。尽管这个出发点不错,但是这样往往会造成用那个语言写出的程序更为复杂。 Mike Cowlishaw,在IBM设计了Rexx脚本语言,他曾经指出,因为语言的使用者远远多于语言的设计者,所以后者必须让位于前者: 一般情况下,只有极少数人会给一门语言编写解释器或编译器,但是却有无数人会去使用它或者依靠它来工作、生活。所以语言必须为大多数人优化,而不是为少数人改进。编译器的作者因此并不怎么欢迎我,因为Rexx是一门非常难以解释或编译的语言,但是我认为这个代价值得,因为它更适合普通人,尤其是程序员使用。 [dagger] [dagger] Dr. Dobb's 期刊, 1996年3月号. 我由衷地赞同这一点。Ruby就是这一理想的化身,实际上Ruby语言本身一点也不简单,尽管它提供了简化编程的方法。由于Ruby的不简单,所以用它编写的程序就可以简单。这一点在其他轻量级语言中也是如此;从实现他们的难易程度看,他们根本不轻量,它们之所以被称为轻量级语言,是因为他们的目的就是为了减轻程序员的负担。 为了了解这一点的现实含义,让我们来看看Rake,一个类似Make,被Ruby程序员广泛使用的Build工具。Makefile使用专门的格式编写,而Rakefile却直接由Ruby编写,它是一种具备全面编程能力的DSL(Domain Specific Language,特殊用途语言)。例29-2,展示了使用Rakefile运行一组测试的例子。 Example 29-2. Rakefile例子 task :default => [:test] task :test do ruby "test/unittest.rb" end Rakefile具有很多来自了Ruby语法的优点: * 方法参数的括号可以被省略。 * 方法的后面可以放置无括号的哈希键/值对。 * 代码块可以紧接在方法调用的后面。 你在使用Ruby编程时也可以不使用这些语法糖衣,所以理论上说,他们是冗余的。经常有一些批评指出这些特性造成语言本身更加复杂。但是,例29-3展示了如果不使用这些特性的话,例29-2的程序会变成什么样子。 例 29-3. 不使用简短语法的Rakefile例子 task({:default => [:test]}) task(:test, &lambda(){ ruby "test/unittest.rb" }) 正如你所看到的,如果从Ruby的语法中去掉这些冗余,Ruby语言本身虽然变得更简洁了,可是程序员却不得不做更多的事情,并且他们写出的程序变得难理解了。所以如果用更简单的工具去解决一个复杂问题,其结果是把复杂性转嫁到程序员头上,这真是本末倒置(put the cart before the horse)。 “ 优美代码”的另外一个重要的元素是灵活性。我这里把灵活性定义为可以摆脱工具的限制。如果程序员由于工具的限制,不得不做违反他们意图的事情,结果只能是紧张和压力。这些压力会对程序员产生不良影响。最终结果根本不会是快乐,并且根据我们对优美代码的定义,这样带来的也根本不会是优美。相对于所有的工具和语言,人才是最宝贵的。计算机应该服务于程序员,使他们开开心心、最大程度地发挥生产率,但是现实中,计算机却经常增加而不是减轻了人的负担。 关于优美代码的最后一点是“平衡”。我上面已经讲过了简短、传统、朴素和灵活。但是没有任何一点可以单独保证程序是优美的。只有当把它们平衡合理地综合到一起,并且从一开始就加以考虑,这些因素才会和谐相处,催生出优美的代码。而且如果你确实从阅读与编写代码中发现乐趣,你就会体会到作为一名程序员的快乐。 Happy Hacking! - -------------- 1. Ruby语言的发明者:Yukihiro Matsumoto - Wikipedia, the free encyclopedia 2. 著名的Lisp程序员,风险投资家和评论家: Paul Graham - Wikipedia, the free encyclopedia 3. 常见的C/C++/Java都是过程式编程所使用的程序设计语言,逻辑式编程的著名语言如Prolog,函数式编程的一些著名语言包括,Lisp及其方言Scheme、Haskell和ML等
__________________ ================================== http://liuxinyu95.googlepages.com liuxinyu95@gmail.com ================================== |