路宁推荐的精益书目

November 17th, 2009

如是我闻…

《精益思想》是必读,其中提到的5个原则十分经典,比较“广泛适用”,但由于太抽象,现在很少有人提及这些原则。我个人认为弄透了这些原则会非常收益。

《金矿》以小说的行事介绍运用精益的全过程。应用的顺序,步骤,态度的转变都值得思考,非常难得。

《丰田汽车案例—精益制造的14项管理原则》我没看,但似乎是没有争议地被普遍推荐。

关于“丰田生产方式”的具体技术细节,有很多书可以参考,留意书名字就知道了。我感觉有时间一定要好好研究制造业的这些具体做法,还是很有启发性的。仅了解那些被无数人升华了好几层的各种“原则”没什么意思,还是要看看原滋原味的实做手法才过瘾。

《精益思想》的姐妹篇《改变世界的机器》和《精益解决方案》同样质量上乘,前者是一个调查报告,时间跨度大,资料翔实,对了解精益的由来,背景和应用概况很有帮助。后者有几个制造业之外的例子,非常生动。

《第五项修炼》介绍了系统思考方法,很像是精益背后的思考工具和理论支持。里面介绍了“系统循环图”,感觉是个不错的工具,一直想用用,还没落实到行动呢。 《精益之旅》前半段介绍原则,总结的不错,后半段是一个故事,足够说明问题

就说这些了,还有像“图解丰田生产方式”,”丰田生产方式“(大爷乃一的),”丰田可视化管理方式“等,都可以帮助了解丰田生产方式的具体做法。

记得是《改变世界的机器》里面,提到了在销售,人事,研发,供应链等方面精益企业与众不同的做法和态度,比较精彩。提到财务方面的书比较少,好像是《精益企业》中有所涉及。

在帮助客户实施敏捷的过程中,ThoughtWorkers常被问到一个问题:有没有一套标准的“敏捷模板”可供快速入门之用?

作为一种强调持续改进的方法学,自然不会有一套放诸四海而皆准的“标准流程”;但对于希望采用敏捷方法的组织和个人而言,若有一组普遍适用的最佳实践作为基础,便能少走许多弯路,以期事半功倍之效。

摆在你面前的,正是这样一本“敏捷入门手册”。

本迷你书从《ThoughtWorks文集》的13 篇文章精选5篇编撰成集。这几篇文章有一个共同点:它们介绍的是一些最根本、最易施行、又最能立竿见影的敏捷实践。藉由这几篇各自独立而又相互关联的文章,我们希望帮助读者从持续集成和测试入手,建立行之有效的项目健康保障体系,并掌握必要的面向对象编程和重构技能,从而切实提升软件质量,并为更进一步的改进打下坚实基础。

如果你喜欢本书,可以 购买原版《ThoughtWorks文集》

或在InfoQ中文站 免费下载这本书(PDF)

这本《 ThoughtWorks文集 》中译本面世之际,也正值“敏捷中国2009大会”召开在即。两者可谓相得益彰。

从2004年进入中国,ThoughtWorks见证和参与了中国敏捷社区的发展历程:从五年前的筚路蓝缕,到如今的欣欣向荣。更令人欣慰的是,在原则、价值观等“大问题”上,敏捷的实践者们已经基本达成共识,社区的话题更加趋于关注实践──这意味着敏捷社区正在步入成熟,将用他们的知识和技能为各自效力的企业创造更大的价值。

我们在这个时候把《ThoughtWorks文集》翻译出版,是希望为社区的发展再尽绵薄之力。作为敏捷方法的积极推动者,ThoughtWorks从多年、多个行业的实践中积累了丰富的经验。本书收录的13篇文章涵盖了编程技术、项目管理、持续集成、测试等方面内容,将带领读者了解ThoughtWorks在软件生命周期各个环节所推荐的工作方式。

比较难得的是,这本《文集》不仅由ThoughtWorks员工撰写,也由ThoughtWorks员工翻译。译者们或是与文章作者素有私交,或是在文章所论述的领域有所专擅,这也使得翻译的质量更有保障。感谢这些译者在工作之余的辛勤翻译,才使这本《文集》如期付梓。他们是:韩锴,胡振波,金明,李剑,乔梁,熊节,徐昊,张晓庆,郑晔。

一本薄薄的《文集》当然不可能解决所有问题,我们更希望它能够收到抛砖引玉的效果。希望ThoughtWorks的经验心得能对国内的敏捷实践者们有所启发,帮助他们做出更多创新,创造更大价值。最后,希望你阅读愉快。

郭晓
总经理,ThoughtWorks中国公司

书中的文章在技术深度、详细程度、新观点/新成果的数量等方面各有千秋,但它们有一个共同的特点:都密切关注实践。这群作者真正做到了思行合一,如此既有思想深度又立竿见影的好书我已多年未见了。

Stefan Tilkov. CEO, innoQ

有这样一家企业,当整个IT行业都对定制软件开发的难度望而却步时,他们敢于挑战这个难题。这本文集让我们得以管窥这家企业内部观点的多样性──这正是他们勇气和力量的源泉。

W. James Fischer. 前CTO/资深合伙人,Accenture

从CruiseControl等大获成功的开源项目,到博客和会议上分享的观点,你都能感受到ThoughtWorks的影响力。身处其外的我们不时会想象,这家公司内部究竟进行着怎样的讨论?这本书就是一个难得的机会,让读者们拉开幕布,参与到讨论之中──你会因此成为一个更出色的软件开发者。

Nathaniel T. Schutta. 作者/讲师/教师

软件开发很大程度上是一种团队活动,团队的领导者将决定最终产品的水准。成功的组织经常不会花时间来记录这些领导者的经验,于是其他人也无法学习这些经验。这本有趣的文集由ThoughtWorks的一组领导者共同编撰,透过这些文章我们能看到ThoughtWorks企业文化之一斑。

Dave Thomas. Bedarra Research Labs

软件开发中最了不起的洞见都出自那些为真实客户解决真实问题的人。然而除了在恒河沙数的博客中淘金之外,几乎没办法找到这些洞见。十年来,ThoughtWorkers解决了大量真实问题,所以当他们决定把自己的经验整理结集,这实在是一件令人欣喜的事。

Gregor Hohpe. 《Enterprise Integration Patterns》作者

这本文集精彩地论述了如何在如今的商业环境下恰当运用编程语言和工具来开发软件。这组作者都是软件世界里身经百战的老兵,他们的经验值得一看。

Terence Parr. ANTLR项目领导,San Francisco大学

ThoughtWorks 素来以其在软件开发上的经验与智慧闻名于世,这本文集出色地汇集了这些经验与智慧,使我们得以从中受益。这本书将被频繁引用,它将出现在每个项目组的书架上。

Jeff Brown. 北美运营总监,G2One

(摘自《 ThoughtWorks文集 》,第6章,“对象健身操”)

规则2. 拒绝else关键字

每个程序员都熟知if/else结构。几乎每种语言都支持if/esle。简单的条件判断对于任何人来说都不难理解。不过大多数程序员也见识过令人眩晕的层层嵌套的条件判断,以及连绵数页的case语句。更糟糕的是,在现有的判断条件上加一个新的分支通常是非常容易的,而将它重构为一个更好的方式的想法却罕有人去提及。条件判断结构通常还是重复代码的来源。例如,状态标识经常会带来这样的问题:

public static void endMe() {
    if (status == DONE) {
        doSomething();
    } else {
        // other code
    }
}

你有很多种方式重写这段代码,去掉else关键字。例如下面的代码:

public static void endMe() {
    if (status == DONE) {    
        doSomething();
        return;
    }
    // other code
}

public static Node head() {
    if (isAdvancing()) { return first; }
    else { return last; }
}

public static Node head() {
    return isAdvancing() ? first : last;
}

在上面的例子中,第二段代码由于使用了三元运算符,所以代码长度从四行压缩到了一行。需要小心的是,如果过度使用“提前返回”,代码的清晰度很快会降低。《设计模式》[GHJV95]一书中关于策略模式的部分里有一个实例,演示了如何使用多态避免根据状态进行分支选择的代码。如果这种根据状态进行分支选择的代码大量地重复,就应该考虑使用策略模式了。

面向对象编程语言给我们提供了一种更为强大的工具——多态。它能够处理更为复杂的条件判断。对于简单的条件判断,我们可以使用“卫语句”和“提前返回”替换它。而基于多态的设计则更容易阅读与维护,从而可以更清晰地表达代码的内在意图。但是,程序员要做出这样的转变并不是一帆风顺的。尤其是你的代码中可能早已充斥了else。所以,作为这个练习的一部分,你是不可以使用else的。在某些场景下可以使用 Null Object 模式,它会对你有所帮助。另外还有很多工具和技术都可以帮助你甩掉else。试一试,看你能提出多少种方案来?

(选自《 ThoughtWorks文集 》第14章)

性能需求采集的重要性经常被人们低估。在这一节里,我将尝试阐明几个重要问题:要度量什么?如何知道我们需要什么?以及如何得到确实有用(而非帮倒忙)的数据?

要度量什么?

最重要的性能度量点有两个:最大吞吐量,以及给定吞吐量下的响应时间。一个好的做法是:分别度量几种不同吞吐量下的响应时间,从中分析负载对响应时间的影响。如果响应的及时性非常重要,那么在确保满足响应时间要求的前提下所能达到的吞吐量可能就会明显低于最大吞吐量。你需要通过度量找出两项数据:当响应时间恰好可以接受时的吞吐量,以及达到预期吞吐量时的响应时间。伸缩性度量的关键则在于:随着数据规模、用户数量或者运行系统的硬件变化,起初得到的性能度量数据会发生怎样的变化。

可靠性的关键度量点是:当负载量高得超乎寻常,或者连续运行了很长时间以后,系统是否仍然正常工作。

如何设定目标?

要想知道系统需要达到怎样的吞吐量目标,你首先需要知道有多少用户会使用这个系统,以及他们的使用模式。用户会多频繁地使用某个功能?这个功能需要多快完成?

业务用户会知道这些问题的答案。你应该让他们明白,你会经常需要向他们咨询这方面的事。然后你应该建立一个良好的沟通流程,以确保信息的获取畅通无阻。

总而言之,你需要有一个可靠的流程与机制来获得所需的信息,使你及时获知支撑业务需求所需的性能指标。如果不经常去计算这些数据,就有可能最后发现你正在朝着已经过时的目标努力。

弄清当前需要负载的吞吐量之后,下一个需要考虑的就是响应时间。在结合UI考虑这个问题时,人们常会有钻牛角尖的想法:既然用户界面要在几秒钟之内响应,那么功能自然必须在更短的时间内完成。但事实并非如此。UI应该立即响应,告知用户:他们的请求已经得到处理;但实际的处理未必马上完成。在整个过程中,系统的其他部分应该照常工作。

响应时间的目标应该主要针对用户界面,并且数值越低越好。而且,不应该期望所有功能都能在同样的一段时间内完成。

如果对前面所说的还不明白,下面我将简单介绍一个采集性能需求的流程。

如何将性能测试融入日常开发流程?

理想情况下,项目组每周应该召开一次会议,确定当前的性能需求。参加这次会议的人应该包括项目经理、关注性能的客户、资深开发者、以及性能测试人员。如果某些性能需求明显无法达到或者完全不合理,开发者就能在第一时间指出。客户的参与是为了提供业务上的信息与知识,从而帮助判断需求的合理性。项目经理需要知道团队做了哪些决定,并提供一些方向性的指导。至于性能测试人员,他们显然应该在场,这样他们才知道需要测试什么。

接下来,你需要找到适当的讨论对象。开发团队需要从客户中找到一个联系人,与他一道决定性能需求,这样才能确保客户和开发者都清楚目标所在。不要把性能需求看作神圣不可侵犯之物,和所有需求一样,它们也应该是开发者与客户对话的起点,双方需要共同讨论决定最终的目标。

一旦需求确定下来,就能决定当需求得到满足时如何向客户展示,并对编写测试的工作进行评估和计划,就跟其他的任务一样。

程序员需要性能测试告诉他们什么?

开发者的需求有很多种,但背后的驱动力总是一致的:如果某段代码需要返工,他们就需要更多的信息来了解当时的情况。这些信息可能来自代码检查工具,也可能来自线程转储,甚至来自日志。他们可能需要知道数据库的忙碌程度,或是负载达到峰值时网络的忙碌程度。

试图预先回答所有这些问题可能并不划算,因为这会需要很大工作量。但我们可以做的是:当问题出现时,弄清哪些信息会有助于开发者解决问题,然后把获取这些信息的任务加到你的任务列表上,并告知客户。此时你就可以判断应该如何进行这些测试:是从此刻开始持续测试,还是只针对眼下的特定问题做一次性测试。

如果开发者的需求以这种方式在会议上提出的,那么所有人都将知道这些需求的存在。客户可以为这些需求排优先级,可以把它们纳入项目计划。最终性能测试将满足各方的需求:它让客户对正在开发的软件保持信心,它也能帮助开发者找到并解决性能问题。

找不到关注性能的客户怎么办?

如果找不到一个关注性能需求的客户,就会有几方面的风险。首先,正在开发的软件可能不符合业务要求,项目可能彻底失败。其次,不管最终的产品如何,客户都可能说它不符合要求,因为他们感觉开发团队没有征求他们的意见。第三,这可能会在团队内部造成紧张气氛,开发团队会觉得自己在被迫做不必要的工作,因为需求不是来自客户──不管项目经理的担心是否正确,这种想法都有可能出现,并导致必要的工作没有被完成,或是相反,开发者们浪费时间去做不必要的工作。

如果客户不懂技术又非要坚持不可能的需求该怎么办?

这种可能性总是存在:客户希望产品的性能达到某个水平,而达到这个水平是不可能或者不经济的。这时你就需要提出一些中肯的问题,把对话引导到真实的业务需求上来,从而打消客户不切实际的要求。

如果客户的要求是关于吞吐量的,可以考虑的问题有:每个工作日处理多少事务?这些事务的时间分布如何?是平均分布还是有明显的高峰期?每个周五下午会有集中访问吗?或者峰值的出现没有特别的模式可循?

关于响应时间,可以考虑的问题有:用户界面的响应时间会对系统的处理能力造成什么影响?能不能把界面与实际的计算操作分离?比如说,可能有这样一种场景:用户输入一些数据,然后进行较长时间的数据处理。此时用户不希望一直等到处理完成,而是希望立即输入下一段数据。所以这时合理的期望不是在一秒钟内完成数据处理,而是将用户界面与数据处理分离,让系统在后台处理前一段数据,同时让用户在界面上输入更多的数据。

以这种讨论方式,我们就能让开发者和客户共同寻找一个对业务价值有意义的性能水平,并且分清什么是当务之急、什么是锦上添花。我们都曾遇到这样的情况:在项目的现有条件下,客户急切希望的某个性能目标不可能达到、或是需要付出高昂的代价。如果相关的分析能尽早开展,客户就有可能在更早的时候做出决定,从而使这些目标成为可能。

如果客户期望的目标不能达成,他们会对最终交付的系统感到失望,哪怕系统其实足以满足业务需求。上述这些讨论有两方面的作用:不仅让开发团队了解客户的真实需求,而且让客户自己也有一个清晰的目标。这样一来,只要系统达到了双方认可的目标,客户就会感到满意。有这些讨论作为基础,客户就不太会坚持不切实际的期望;如果他们仍然感到失望,至少那也是出于合理的原因。

何不让业务分析师一并采集这些需求?

采集性能需求时不一定需要业务分析师在场,原因有几点:首先,此时功能需求的采集应该已经完成了;其次,即使业务分析师在场,开发者还是不能缺席,因为分析性能问题需要获得哪些信息只有开发者才清楚,也只有他们才能判断获得这些信息的途径和难度。性能测试人员应该提出前面介绍的这些问题,以此推动讨论进行,他们也能够判断每个需求是否容易测试。所以,当这些人坐在一起讨论时,业务分析师大可以把时间花在其他更有价值的地方。

小结

需求采集是为了让所有人都清楚:最终交付的产品需要有怎样的性能才能支撑业务目标。之所以要让客户参与,是因为他们最了解自己的业务,这样才能确保采集到的需求足够准确。而且通过讨论也能帮助客户清晰自己对性能的需求,从而有效管理他们对系统的期望。

(摘自《 ThoughtWorks文集 》,第1章。)

作为一家公司,ThoughtWorks汇聚了一批热情洋溢、积极主动、才智过人的员工,他们为客户提供定制软件开发以及切合实际的咨询服务。如果你问一个ThoughtWorker,这家公司最让他最喜欢的是什么,他很有可能会告诉你:正是那些朝夕相处、并肩工作、彼此学习的同事们。在这个群体里融合了技术极客、管理者、分析师、程序员、测试员和行政人员,他们有着不同的种族、文化和教育背景。这种背景和视角的多样性,再加上坚持正确观点的热情,引发了很多活跃的讨论。

如今ThoughtWorks拥有近千名聪明而有见地的员工,在全球6个国家设有分支机构,组织内部几乎没有任何层级,并且一以贯之地坚持信息透明。可以说,我们已经创造了一家成功的企业。但我们对“成功”的定义远不止于此:一家企业的成功不仅意味着让客户满意,还应该对整个行业乃至整个社会产生正面的影响。我们有着更高的目标。

在博客世界里,在技术大会的会场中,在互联网上,在书架上,我们都能听到ThoughtWorker的声音。在不断追求卓越的过程中,我们会近乎冷酷地剖析自己曾做过的事、以及做这些事的方法,以寻求改进之道──在这方面我们永无饗足。在上下求索之中,一旦学到了什么知识,我们就希望与他人共享。

...

这本文集所收录的文章虽然各自成篇,彼此之间却有着千丝万缕的联系:它们共同展示了一片布满迷雾的IT丛林,以及一条条或显而易见、或出人意表的林间小径。文章选题跨度之宽、解决问题的办法差异之大,恰能反映众位作者所在的这个组织为各种思想的萌生营造了一个健康的环境。阅读这本文集恰如管中窥豹,让我迫不及待地想看到这些才华横溢的同事们为整个行业、整个社会创造更多。

程序员的高产与否和地域无关。我供职的ThoughtWorks是一家素以其独特的企业文化而闻名的跨国咨询公司,当我遇到来自其他国家(包括中国)的ThoughtWorks员工时,我们之间总是相似多过差异。在我看来,不管来自哪个国家,软件开发者总是我们的第一身份,然后才是国籍和文化的区别。

世界各地的软件开发者都大致相同,也就是说我们在尝试提高生产率时也面临同样的挑战。正因为如此,在听说《The Productive Programmer》一书被翻译成其他语言(当然也包括中文)时我才会如此高兴。我希望书中所有的技巧与思考都能原汁原味地翻译给具有不同文化背景的读者,更希望这本书能帮助它的读者们变得更加卓有成效,不论他们来自哪个国家。

Programmer productivity has no geographic boundaries. I work for ThoughtWorks, an international consulting company known for its strong corporate culture. When I meet ThoughtWorkers from other parts of the world (including China), I’m struck more by our similarities than our differences. To me, developers from other countries are developers first, and citizens from another culture second.

Developers are pretty much the same all over the world, meaning that we face the same challenges for productivity. That’s why I was so glad when I heard about the translations of The Productive Programmer to other languages, including (obviously) Chinese. I hope that all the techniques and concerns translate to another culture easily, and mostly I hope that readers from no matter what country find that this book makes them more productive.

(样章试读请见 《卓有成效的程序员》CSDN宣传页面

China-pub的推荐页面这本书 夸成了“影响全球程序员的经典之作”、“航标灯塔般的经典名著”、“脍炙人口的传世之作”…唔,不过,又加上了这么一句:

如果您是一名刚踏入编程开发领域的新手,我们幸庆你可以阅读到《卓有成效的程序员》,因为它可以告诉你作为一名优秀的程序员你应该具备的思考模式和优秀习惯。

与此同时,PHPChina的cnkiller写了一个 很有意思的书评

我是你《卓有成效的程序员》的一个读者。在这里,我非常的想和你说一下,你是我的敌人,我要像你挑战,你接受吗?

曾经,无论是从那个方面,我在别人的眼中是一个计算机高手,我错了,我从一开始就错,我如果不是一开始就这么认为,我现在就不会这么低落,如果我不低落,我就不会错了…...(什么?你听不懂?那你得去看看我国的《武林外传》,就知道我在说什么了)

看过你的书之后,才知道什么是正真的高手,而我,就从高手的夷为菜鸟。

周伟明的推荐语也令人感动

程序员总有学不完的东西,许多看过我写的“程序员的十层楼”的人觉得自己仍然是“菜鸟”。同样,当我看到Neal的这本书时,发现自己十几年的程序员生涯仍然是一个低效的程序员,书中介绍的许多提高效率的工具和方法以前没有用过或没有用好。要是在“菜鸟”或“大虾”阶段就能看到这样一本好书多好啊!

第一,我喜欢的书别人也喜欢,很美好。第二,如果所有程序员都像这本书里所说的那样工作,这世界该多美好。

实施敏捷要不要面面俱到? 其实这本 《卓有成效的程序员》 已经从另一个角度给了我们答案。就像我在 译者序 里说的,

在钢铁厂,泰勒的科学管理方法让一个搬运铁块的工人每天的工作效率提高了3倍;而在软件开发中对细节的重视甚至能让程序员的效率提升更多,因为人的体力终归有限,而脑力的开发程度则远未达到极限。

那么反过来想想,如果只有方法学没有细节,难道不是会让浪费成倍增加,效率成倍降低吗?那么这种脱离细节、无助于提高生产率的“敏捷方法学”、“敏捷专家”,要来有什么用?(所以一个SCRUM Master证只值4000块──这是成交价,花一万块去培训的master们下次记得要讲价。)

所以,友情提供参考判据:如果一个自称“敏捷专家”的家伙告诉你,搞敏捷用不着面面俱到,什么结对编程啦持续集成啦测试驱动啦,没有也没关系,不影响你搞你的敏捷…

  1. 请想想你是不是喜欢一个对提高生产率没啥帮助的敏捷。
  2. 这个家伙很可能就是个只值4000块的敏捷专家──他之所以这么说,是因为他自己也做不来。

消除浪费,始于细节

March 18th, 2009

《卓有成效的程序员》 译者序)

在一次关于敏捷的讨论中,我说了一句令很多人不解的话:我不要敏捷。

和很多话一样,断章取义的理解很容易造成误会。我当时说的整句话是:我不要敏捷,我要致力于消除软件开发中的一切浪费。当“敏捷”渐渐变成一个人见人爱的“大词”,越来越多的人开始发现,其实自己要的不是“be agile”,而是切实地消除浪费、提高效率。

所以,作为ThoughtWorks员工的Neal Ford在他的这本书里闭口不谈“敏捷”。他只是实实在在地告诉你,作为一个程序员,你每天都在什么地方浪费着自己的生产率,以及如何去有效地消除这些浪费。

也许你甚至意识不到这些细小环节上浪费的存在。随便举个例子吧,在你一天的工作中,你有多少次从资源管理器里导航到源代码文件夹查看代码,然后又导航到另一个文件夹寻找文档,然后打开命令行窗口并进入项目目录,以及在密密麻麻的任务栏里找到正确的浏览器窗口?Neal Ford说,这些都是浪费:做这些与核心任务──软件开发──无关的事情是在浪费生产率。有兴趣知道这些自己每天做无数次的事还能如何改进吗?即便不是专业程序员,这本书的第2章也将对你不无裨益。

从某种意义上来说,Neal Ford在这本书里做的事,正是现代科学管理理论的鼻祖弗雷德里克·泰勒在伯利恒钢铁厂做过的“泰勒实验”:剖析每个个体日常工作中的每个细节,对细节进行持续优化,通过对细节的改进提升生产率。在钢铁厂,泰勒的科学管理方法让一个搬运铁块的工人每天的工作效率提高了3倍;而在软件开发中对细节的重视甚至能让程序员的效率提升更多,因为人的体力终归有限,而脑力的开发程度则远未达到极限。

这并非痴人说梦,因为ThoughtWorks就是这样的例证。据说ThoughtWorks有一群天才的程序员,只有近距离接触才会发现,这些人之所以能做到如此高效,很大程度上是因为他们有一些根深蒂固的好习惯,而且不断在细节上精益求精。ThoughtWorks中国公司的几位同事一起来翻译这本书,也正是为了把我们的经验分享给更多人。

从每天的细节开始,让自己成为一个高产的程序员,其实每个人都能做到。

熊节
ThoughtWorks,咨询师
2008年11月17日

懒于行,是故勤于思

March 16th, 2009

首先感谢李剑为这本 《卓有成效的程序员》 所做的 推荐序

如果你想做一个真正的懒人

就请继续读完这本书

因为这本书是天堂

很显然要想做一个行动上的懒人,要让计算机拼命的跑而自己有点空闲抽根烟,需要花很多心思。不然,很容易就会变成Neal Ford说的,人们忙忙碌碌干些重复劳动,计算机扎堆闲聊嘲笑这些勤快人。

计算机应该用于执行重复劳动。而人,尤其是程序员,应该保持对重复劳动的敏感与不妥协。每个网址输入相同的“www.<domain>.com”是重复吗?每次循环写同样的for…each是重复吗?每个项目copy同样的一堆配置文件是重复吗?每天打开资源管理器进入同一个目录是重复吗?

所以,很大程度上,程序员的高效与否,与这种对重复的敏感与不妥协程度,有着必然的关联。如同强迫症一般,发现一切隐藏着的重复劳动(或者说,浪费),势必除之──自动化之──而后快。这不仅仅是生产效率的问题,更是自我完善的过程。

(BTW,一切把程序员与建筑工地上搬砖的工人做类比的人都应该被拖出去挖坑埋掉。软件的一切价值就在于消除重复劳动。软件领域中一切能够被自动化的工作一定会被自动化。连这一点都看不出来还妄谈软件的人应该被强制收声。)

偷懒是一项需要很多思考来完成的任务。很不幸(或者幸运)程序员是被认为应该为这个社会做这些思考的人。这就是这本书存在的原因。

Web开发大全:Ruby on Rails版

Rails的创造者David Heinemeier Hansson这样说:“我从来不会为了学一种语言而学一种语言。我学习新的编程语言一定是要用它来做点什么事。”同样的道理,很少有人只是为了学习漂亮的设计而开始接触Rails,大部分人──就像我一样──是抱着一个功利的念头开始自己的铁道之旅的。“我要做一个网站,听说有个叫Ruby on Rails的东西做网站又快又好,我得看看这是个什么玩意。”──大抵是这样的念头。

所以,Rails的学习者们真正要的不是深入理解Rails,而是又快又好地做出自己设想中的网站。

这年头的网站创业者们想要的不是“Ruby on Rails做的网站”,而是一个具有各种2.0特质的、很酷的网站。“什么mashup啦、widget啦、AJAX啦、REST啦,能用的全给它用上。你要是URL里还带一问号啊,你都不好意思跟人打招呼。每个页面放一地图,甭管有事没事都往地图上标记,倍儿有面子。这网站就够牛了吧?那是基本要求,还得在多种环境部署,高性能的服务器环境一个脚本就得部署好。你想啊,那些做一个功能都只花15分钟的程序员,根本没心思用俩小时做一次部署。所以我们的要求是:不但要酷,还要敏捷。”程序员们面临的大概就是这样的挑战。

诚然,作为入门手册的《Web开发敏捷之道》(Agile Web Development with Rails)在实用性方面做得已经不错了,一位初学者可以跟着那本书做出一个像模像样的玩具网站,同时对Rails的方方面面有个大致的认识。不过当他们尝试动手做自己真正想要的那个网站时,就会突然发现面前赫然立着两只拦路虎:第一,真正的网站不是玩具,有太多真实世界里的常见问题他们不知该如何解决;第二,Rails一向秉承“做一件事并且做好”的Unix设计传统,这也就意味着要做一些真实有用的功能往往需要很多Rails之外的相关知识。这可真是件令人沮丧的事情:花了好几天工夫来学习Rails,自以为已经习得一身好武艺,一出山门却发现面前摆着那么多难题不会解决,甚至想翻书都不知该从何翻起。

简而言之,他们没有套路。

这本《Web开发大全(RoR版)》就是帮这些踌躇满志的网站初哥们解决套路问题的。这几位实战经验丰富的作者各出高招,简单介绍Rails之后,立即把用户管理、内容展示、文件上传、搜索、RSS等等网站“家常菜”给抽丝剥茧地细细解说一遍,再把各种常见的mashup逐一介绍,尤其是为地图服务这个重要的2.0元素单辟章节(值得一提的是,撰写这一章的高昂乃是中科院地理所的博士,从他的专业角度来介绍互联网上的地图服务,可谓高屋建瓴鞭辟入里,不可不读)。讲完开发的内容,部署工作也没有被忽视,第十章“部署演练”介绍了各种曾经或正在或即将流行的Rails应用部署方案,特别是关于JRuby on Rails的介绍引人注目:这是将Ruby on Rails和J2EE两个世界结合起来的纽带,ThoughtWorks的第一个商业产品Mingle就采用了这种部署方式。

这是一本有套路的书。看完这书的读者应该能学到网站开发的套路。

最后我还得夸赞一下这几位作者。从中国有Ruby on Rails社区开始,这几位就个顶个的是社区里的积极分子。他们为Rails在中国的发展起了重要的推动作用。有骆古道这样远赴重洋心系祖国的爱国程序员,有王大力这样组织和掺合全国各地各种技术活动的热心大叔,有董斌、苏锐这样长年在互联网一线奋战的技术中坚,有黄翀、高昂这样醉心技术深度广度俱佳的有为青年,这么一群靠谱的人和博文视点这么一家靠谱的出版商一起创作的作品,理当是一本靠谱的书。

所以,怀揣梦想的Rails爱好者们,拿起这本靠谱的书,上路吧。

大师级著作

December 28th, 2007

本书的审阅者们给我的手稿提供了清晰而又及时的反馈,为此我要感谢Erich Gamma、Steve Metsker、Diomidis Spinellis、Tom deMarco、Michael Feathers、Doug Lea、Brad Abrams、Cliff Click、Pekka Abrahamson、Gregor Hohpe和Michele Marchesi。

什么样的作者能请得动这样一批审阅者?什么样的书当得起这些人来审阅?

InfoQ的书评

Kent Beck的新书《实现模式》是一本关于如何撰写Java代码的书。本书中的模式,是基于Kent对现存代码的阅读以及他自己的编程习惯而形成的。这些模式来自他早年使用Smalltalk模式通过代码与其他开发人员进行沟通的过程。它们的级别相对设计模式较低,与Larman提出的GRASP模式处于同一粒度。本书中的模式试图为如何撰写大家都能看得懂的代码提供一个清晰明确的视角,并告诉你这些代码如何为人的需要和降低成本的需求提供保障。