本书针对软件开发,提出了一些相当棘手和敏感的问题,并给出了颇具争议性的结论:从一个数百年来一直兴旺发达的系统——工艺学中获得启示,寻找答案。
本书用5个部分共19章的篇幅,系统地阐述作者的观点,并试图回答一直困扰着软件行业的难题——我们应该如何重组软件构造的过程,使其能够如我们所愿地有效运转?第1部分共4章,对传统的观点提出质疑——软件工程真的是解决软件开发问题的灵丹妙药吗?第2部分共2章,这一部分提出了本书的观点,即以软件工艺的视角看待软件开发。第3部分以7章的篇幅,从不同的角度全面地展现了软件工艺理论所带来的主要变化,以及如何实践这个观念。第4部分共3章,对比了软件工艺与软件工程,并为各自适用的范畴重新划定了界限。第5部分共3章,分别讨论软件开发中的权宜之计和长期问题。
本书荣获2002年度Jolt图书大奖。阅读本书,有助于引发读者在软件开发问题上的独立思考,本书适合软件行业的所有从业人员阅读参考。
第一部分 置疑软件工程
第 1 章 理解软件工程 3
软件工程的悖论 4
等待硬件开发时,软件开发者在干什么? 5
得到可用的硬件之后,软件开发者如何
加快交付的速度? 5
传统开发过程的内蕴 6
软件工程的当代解读 7
“足够好”的软件—庶民的软件工程 9
软件工程适合你的项目吗? 10
第 2 章 软件工程的困境 11
“有组织的、可计量的”软件开发过程现
实吗? 14
我们当然可以将软件开发中的某些部分
自动化,不是吗? 16
“足够好”的软件开发方法的危害 17
谁能取代软件工程? 19
第 3 章 理解软件开发 21
软件资产 23
软件开发需要团队协作 25
软件开发的分工有用吗? 26
没有一劳永逸 27
寻找比“软件工程”更合用的隐喻 30
第 4 章 寻找一个比软件工程更好的隐喻 33
软件开发的工艺 35
与传统工艺学的比较 37
软件开发工艺的复兴 38
第二部分 软件工艺
第 5 章 重拾软件开发 45
工艺学致力于改善软件开发的现状 46
工艺学鼓励开发者编写优秀的软件 47
吹响号角 48
第 6 章 无须执照的工艺学 51
工艺是私人性的 51
同行认可和推荐是获得更好软件的办法 52
执照只是假象 53
执照是在向风车开战 55
工艺学关注个人 57
软件开发者不是太少,而是太多 57
第三部分 软件工艺隐含的意味
第 7 章 工艺学对系统的用户有何影响 65
软件容易拷贝,所以软件工艺能够有效 66
批量市场的难题 67
工匠与用户有一种不同的关系 69
但是,请记住:购买者很可能不是
使用者 70
优秀的软件应该签上开发者的名字 71
为作品签名会使情况发生变化 72
工匠应当对作品负责 72
工匠需要挑剔的用户 73
更小、更坚固的软件更有利于用户 73
软件工艺带来协作式开发 74
第 8 章 顾客与工匠的关系 75
给我一个真实的交付日期 75
揭穿“足够好的软件”的谬论 76
另一种选择 78
不要只考虑出价最低的开发者 79
差劲的客户将很难吸引优秀的开发者 80
让软件工匠因为自己的作品而获得荣誉 80
要求开发者对作品负责 81
利用开发者之间的差异 81
雇佣优秀开发者组成的小团队 82
优秀的开发者究竟值多少? 83
但我们如何知道开发者有多优秀呢? 84
根据交付的成果来衡量开发者的水平 85
在选择工匠时,客户在成本和质量之间作
出权衡 87
软件工匠的专业分工 88
客户与软件工匠有长期的联系 90
维护者是一个荣耀的身份 90
软件工艺有益于长期使用的软件 92
客户与软件工匠志趣相投 92
第 9 章 工匠的管理 95
软件工匠不是雇工 96
好的开发者比管理者更有价值 96
软件开发的实际过程无法详细定义 97
软件工匠与管理者的关系 98
以管理优秀的开发者为乐为荣 98
优秀的管理者理解项目的节奏 99
软件工匠喜欢创造软件 100
软件开发的根本从来没有改变过 100
家有一老,如有一宝 101
软件工艺要求全新的管理方式 103
软件工艺不是“有计划报废” 103
软件工匠坚持自己的要求 104
第10章 成为软件工匠 107
软件工艺拒绝精细的分工 107
过度的专业化会延误开发、导致错误 108
软件工匠建造能够理解的系统 109
工艺学需要献身精神 109
如何成为软件工匠? 110
学徒是比学校教育更有效的学习方式 111
技师是工艺学传统的关键 111
工艺学传统已经延续多年 112
第11章 工艺的掌握 115
软件工艺大师是什么样子? 116
善用你的老员工 116
“掌握技艺”意味着使用稳定的技术 117
软件工匠不会仅仅因为工具“最新最好”
而使用它 118
软件工程对COBOL的谋杀 119
技艺需要花时间去掌握 120
“掌握”意味着承担起传递工艺的责任 121
工匠挑选学徒和技师 122
第12章 学徒开发者 123
我们必须扭转开发者培训质量下滑的局面 123
大学文凭与项目开发无关 125
会编程不等于会开发软件 125
如果必须送初学者去培训,选择好的
培训课程 127
工艺的掌握,学徒比培训更有效 127
成为学徒是重要的一步 128
为了降低对工作的影响,工匠慎选
学徒 128
重要的是学,不是教 129
学徒不是学校 129
活到老学到老 130
学徒审查师傅的作品,并从中学习 131
学徒的角色 132
从低风险的任务开始 133
晋升到产品开发 133
因为能力而晋升 134
学徒不是廉价劳动力 134
学徒期是时间和精力的投资 136
学徒如何成为技师 137
第13章 技师开发者 139
技师在工艺学传统中的位置 140
技师开发者 140
技师很少单独工作 141
技师关注应用程序的交付 141
技师在软件工艺中扮演关键角色 143
第四部分 重新定位软件工程
第14章 软件工程项目 149
软件工程的目标是大型系统项目 150
软件工程需要专业分工 151
软件工程项目依旧使用瀑布过程 151
编程是一项刻板的工作 152
软件开发不是软件工程项目的瓶颈 152
形形色色的软件工程项目 153
敏捷方法代替缜密的软件工程 154
第15章 “软件工程”隐喻的危害 155
无法以低成本实施软件工程 155
鱼与熊掌可以兼得? 156
相信估算软件工程项目的确需要
很长的时间 156
软件工程鼓励“科学管理” 157
软件工程轻视不精确的讨论 159
软件工厂:软件的生产线 160
跨项目复用极难实现 161
冒险的“长时间复用” 162
“标准软件开发过程”的迷思 164
传统的分工无助于软件开发 165
“最佳实践”是“科学管理”的遗毒 166
最佳实践使人墨守成规 166
最佳实践阻碍了过程革新 167
软件工程强迫我们忽视个人 168
软件开发者不是可替换的资源 169
伪造一个“理想的开发过程” 169
开发过程,不嫌其多 170
抛弃软件工程的瀑布式过程 171
瀑布方法需要大型团队来实施 172
小型团队绝不要尝试软件工程 173
第16章 学习软件工程的经验 175
尺度和复杂度 175
做软件,不容易 176
应用程序需要良好的结构 177
变化的代价很高——如果你不允许变化
的话 178
交流至关重要 179
文档总是错的 180
用增量式开发来控制风险 180
精确的估算很难得到 181
借用这些经验 183
第五部分 星期一的早上
第17章 经验——项目成功的指示灯 189
根据声望选择软件工匠 189
信任工匠的推荐 190
最后,开始大范围搜索 191
根据声望和作品来评价工匠 191
考察工匠的作品 192
工匠的试演 193
由软件工匠来组建开发团队 194
根据个人了解和推荐挑选团队成员 194
年富力强的开发团队 195
为低预算团队担心 196
通力协作 196
使用增量式开发 197
尽早解决问题 198
任何人都能学会协作式开发 198
回避极端技术 199
经验的价值 200
他们去年在哪里? 201
奖励优秀开发者 201
想要人才,就得付高薪 202
我们付得起那么多钱吗? 203
做好吃惊的准备 204
第18章 为测试和维护而设计 207
是软件应用,不是软件项目 208
应用程序只会退休,不会结束 208
维护团队理应拒绝丑陋的软件 209
可维护软件需要有自动测试 209
使应用程序能够被测试 210
为维护而设计 211
创建可维护软件需要经验丰富的
开发者 212
可维护软件能够生存多年 213
长寿的应用程序需要长寿的开发工具 213
开放源码,软件工艺的最爱 214
Java对项目的健康有害 214
可维护软件需要稳定的基础设施 215
优秀的软件是全球性的 216
保证软件的全球性 217
拒绝“有计划报废” 218
优秀的软件需要优秀的用户界面 218
能够安全使用的软件 219
可维护软件易于诊断 220
外包的危害 221
外包忽视了软件开发的本质 222
在外包中坚持软件工艺 223
借助外来的工匠 224
维护是软件生命中最重要的部分 224
提高维护者的地位 225
维护者当受赏 226
并非所有软件都必须可维护 226
“为测试和维护设计”不能一蹴而就 227
第19章 活到老,学到老 229
创造学习的环境 229
用内部研讨创造学习环境 230
邀请所有人参加讲座 231
学习时间是一种投资 231
掌握软件开发的技艺 231
鼓励参加用户组和技术会议 233
慎选培训课程 234
课前联系 234
课后跟踪 235
亡羊补牢 235
鼓励员工活跃于开发者社群中 236
鼓励出席技术会议 236
鼓励开发者担任讲师 237
鼓励开发者写书 237
沉思的实践者 238
时隔一年之后,当我再次到AMAZON寻找这本《软件工艺》时,它的评价不知何时已经悄悄地变成了四星半,销售排行也已经到了5,000多名——熟悉AMAZON的读者应该知道,在AMAZON能得到四星半评价的已经是精品好书,四位数的销售排行就更能证明它的品质。可是,一年前看到的批评仍然历历在目:“过时的例子”、“混乱的逻辑”、“东拉西扯不知所云”……当这些尖锐的言辞与“所有软件管理者的必读书目”一类溢美之词并列时,我不得不再次认真地思索:这究竟是一本怎样的书?
Pete McBreen说,这本《软件工艺》是一本“极具煽动性”的著作。而在我看来,用“煽动性”来评价它只嫌太客气,或许“颠覆性”会是一个更贴切的词。自1968年NATO会议以降,软件工程的话语就始终把持着软件业(以及软件学科)的言路。一切的软件问题都不由自主地被归咎于“软件危机”,同样自然地,一切的解决方案都不由自主地被划入“软件工程”的范畴。从记事以来……呃,我是说,从上大学以来,我们的一切讨论都围绕着软件工程展开:这样做是否符合软件工程?如何对软件工程加以改进?企业应该如何开展软件工程?凡此种种。在语词的不断重复与变调之间,“软件工程”逐渐被捧上了神坛,成为一种信仰,并因此失去了它旧有的价值与意义。君不见,即令是软件工程的反对者,也只能说出“我们不要软件工程”这样的话——仍然未脱软件工程的话语霸权。
Pete McBreen是一个极其敏锐的人,并且对语词背后的意蕴有着深刻的体认,这或许与他年少时在英国所受的教育有关吧。他一针见血地指出:软件并不是工程,“软件工程”仅仅是一个多少有些不够贴切的隐喻而已。是的,一个隐喻,正如我们常说的“桌子腿”、“针眼”一样,这是一个深入人心、渗透极广的隐喻。但是,尽管每个人都知道绣花针并没有长眼睛,我们却常常忘记了软件工程作为隐喻的本来身份,真心诚意地把软件作为一种工程来对待了。软件工程的困境与读到这本《软件工艺》时本能的拒斥,殆出于此。
钱钟书曾说,反其道以行也是一种模仿。而对于目前软件工程的反对者们,另一个更恰当的比喻是“反转的胶片”——胶片的颜色与照片完全相反,但两者记载的信息却是毫无二致。作为一个真正意义上的颠覆者,Pete McBreen为软件开发找到了另一个隐喻(以及随之而来的另一套语词),那就是本书的标题——软件工艺(software craftsmanship)。
对于这套工艺学的语词,我一直有着淡淡的隐忧。在西方,工艺学传统多半与文艺复兴的人本主义联系在一起,而在对现代性的反动中,文艺复兴一直是吸引大众的旗帜。因此,可以想象,“软件工艺”这样一个隐喻对于欧美程序员有着不可抵挡的诱惑。而在中国,“学而优则仕”的传统价值观固有地鄙薄工艺学的实践者,“五四”以降现代性的话语又早已根深蒂固,所以我实在不敢乐观地期望这个译本的读者能够让“软件工艺”的思想畅行无阻。好在Pete McBreen并不是一个太喜欢夸夸其谈的作者,书中的论述虽然大胆,却是有理有据。既然Fred Brooks的“没有银弹”已经深入人心,相信以逻辑思维见长的软件开发者们能够抛开对软件工程的迷信,随作者一道认识软件工程的局限,并由此生发对软件工艺的思索。倘如此,这本书也就算不辱使命了。
在你开始正式阅读本书之前,请允许我给你打一针预防针:这本书可能颠覆你浸淫其中数年甚至十年的软件观,所以书中的很多观点可能让你感到出离惊奇甚至出离愤怒。请你不要马上把它扔到墙角去,阅读的过程也就是习惯一种话语方式的过程。当你逐渐习惯软件工艺的话语方式之后,或许能从中找到一些自己需要的东西。
为这个译本,我要感谢UMLChina的站长潘加宇,是他把这本书硬塞到我的手上,让我没有与这本精彩的著作失之交臂。我还要感谢我的女友、本书的合译者马姗姗,她优雅的文笔弥补了我言辞的生涩,她的支持与鼓励让我能够在工作之余顺利完成此书的翻译。谢谢你,亲爱的姗姗。
最后,希望你能从这本《软件工艺》中找到别样的触动和欣喜——就像我曾经的阅读体验。
熊节
2003年8月9日星期六 凌晨
杭州
Pete McBreen是一名独立顾问,对软件开发情有独钟。尽管将很多时间用于写作、教学和顾问工作,但他仍然坚持每年至少在一个真实项目中亲手从事编程工作。Pete特别善于为软件开发者面临的问题找到创造性的解决方案。在过去的很多年中,他参与了各种正式和非正式的过程改进活动,所以他能够以超然的态度看待软件业普遍存在的问题,并敏锐地意识到:“软件开发理应有其乐趣。否则,开发过程就是错的。”Pete住在加拿大亚伯达省的小镇考昆,没有再回到大城市居住的计划。
他还是Questioning Extreme Programming一书的作者。
用“工艺学”来比喻软件开发,这可以看成是对软件开发的一次追根溯源:优秀的软件开发者们一直都知道,编程的确就是一门工艺技巧。不论软件开发者拥有多少纷繁芜杂晦涩难懂的知识,但最终左右着应用程序开发的仍是那种不可言说的感觉和经验。举个最简单的例子:也许有人能够了解Java语言所有深奥幽暗的技术细节,但除非这个人能培养起自己对于软件的审美感觉,否则他永远无法真正精通应用程序的开发。而与此相反,一旦某个人获得了那种软件开发的感觉,特定的技术细节就变得几乎完全无关紧要了。优秀的开发者总是在不断地学习、使用最新的技术和技巧,对于他来说,学习一门新的技术只是软件开发者生涯中的家常便饭而已。
“软件工程”这个词是由NATO属下的一个研究组在1967年提出的,这个研究组还提议召开一次会议,专门讨论“软件所面临的问题”。1968年,由NATO科学委员会主办的这次会议在德国迦米许*召开,会议提交的报告就被命名为《软件工程》 。在这份报告中,Peter Naur和Brian Randell这样写道:“我们之所以选择了‘软件工程’这个颇具争议性的词,是为了暗示这样一种意见:软件的生产有必要建立在某些理论基础和实践指导之上——在工程学的某些成效卓著的分支领域中,这些理论基础和实践指导早已成为了一种传统教义。”
和他们一样,本书之所以选择了这样一个颇具争议性的书名(并提出了很多颇具争议性的观点),是为了暗示这样一种意见:软件开发的实践者们有必要开始关注软件开发的工艺。软件工艺是如此重要,因为它让我们摆脱“制造业”的隐喻(这个隐喻正是软件工程所带来的),并让我们开始关注从事软件开发工作的人。软件工艺带来了另一种隐喻:拥有技术的软件开发者抱定决心要掌握自己所从事的工艺,对自己的劳动成果负责并以之为荣。
软件工艺并非与软件工程或者计算机科学针锋相对格格不入。与科学和工程学相比,软件工艺是另一种完全不同的教义,但又能与这两者很好地共存,并从中获益。现代的铁匠能够因为更好的工具、原料和知识而获益;同样,软件工艺也能够因为更好的计算机、可复用的组件和更先进的编程语言而获益。铁匠们在自己的工作中融入了技巧和艺术,从而超越了科学和工程学的范畴;同样,软件工艺能够指导开发者生产出优秀的应用程序及系统,因此也可以超越计算机科学和软件工程学的范畴。对于这一论点,最好的佐证大概就是UNIX和现在的GNU Linux了——这两个系统之所以能够获得如此巨大的成功,完全是因为它们的创建者拥有精巧的手艺、高超的技术和无私的奉献精神。
很长时间里,人们一直试图强迫商用软件的开发适应软件工程的要求。这种削足适履的做法引发了不少的问题,而软件工艺则给这些问题带来了答案。软件工程的发展,很大程度上是为了满足NATO成员国开发超大型国防系统的需要。而商用软件的开发与军用系统、政府系统的开发却有着天壤之别:商用软件的规模通常比较小,并且开发时间通常不能超过18个月。只有极少数商用软件是由超过20人的团队所开发的,大多数开发团队都不会超过10人。对于拥有200人以上的大型团队,软件工程能够很好地解决他们所遇到的问题;但对于“团队中的个人应该如何锻炼自己的技艺”这个问题,软件工程却几乎没有任何论述。
软件工程鼓励在软件开发中使用人海战术 。软件工程不但没有解决“如何培养拥有高超技艺的开发者”这个问题,反而试图降低对软件开发工作的技术要求——软件工程认为:只要投入更多的人手,所有的问题都可以得到解决。这实际上就是在暗示:如果可以拥有大量技术水平较低的开发者,那么我们就不需要那些技术超群的“高手”。
尽管人海战术有时能够成功,但最终得到的软件多半也是垃圾:它们多半臃肿迟钝,总是无法令人满意。用户被眩目的图片和动画搞得晕头转向,但就是无法真正掌握软件的用法。由于无力学会使用整个软件,他们会有强烈的挫折感,并只使用很小一部分功能来满足自己的需要,而更多的功能则根本无人问津。
软件不一定非得要像这样的。
我时常看到这样的软件开发团队:他们开发出真正有价值的应用程序、为用户的业务提供了实实在在的帮助,却因为没有遵循软件工程的最佳实践而懊恼不已。其实,他们大可不必这样想。在我看来,唯一能够检验团队能力的标准,就是看他们能否按时发布用户需要的软件、并在随后的时间里不断地补足、扩展这个软件。按时发布第一个版本固然重要,但始终及时地发布后续版本、并保证每个新版本都在原来的基础上有所提升,这可能是更加重要的。
常常有人问我“如何雇佣好的开发者”。面对这个问题,我的回答总是:去找那些成功地开发过几个应用程序、并在交付后仍然留在项目组中直到下一个升级或维护版本发布的开发者。能够交付最初的产品,就说明这个人有能力开发出可用的产品;参与第二个版本的开发则使他有机会反思自己最初的开发方式带来的效果。如果某个开发者把这样的过程重复了三遍,我敢打赌他在软件开发工艺方面已经拥有了足够的技能和经验,这将使他能够继续获得成功。
在本书的书名中,我把软件工艺称为“新的渴求”。之所以这样说,是因为我发现软件开发社群中的很多人开始盲目地追逐新技术,而忘记了真正重要的东西。软件开发的终极目标是要创建出高质量的、坚固的软件程序,并使之为用户创造价值。现在,我们的当务之急就是要培养出新一代的合格开发者,让他们拥有实现这一目标的能力。
“为用户创建应用程序”的过程曾经是妙趣横生、激动人心的,但软件工程几乎完全抹杀了这种令人愉悦的体验。现在,软件工艺将把软件开发过程中的乐趣和激动重新还给软件开发者。
Pete McBreen