基本信息
- 原书名:Clean Code: A Handbook of Agile Software Craftsmanship
- 原出版社: Prentice Hall PTR
【插图】

编辑推荐
作者Martin是软件工程领域的大师级人物,是《敏捷软件开发:原则、模式与实践》、《敏捷软件开发:原则、模式与实践(C#版)》(邮电)、《*限编程实践》(邮电)等国内引进的畅销书的作者,其中**本原*荣获美国《软件开发》**3届震憾(Jolt)大奖,Martin的敏捷系列书是软件工程界的**书籍。本书是他的又一*新力作。
Martin在书中对代码具有革命性的解读,阐述了整洁代码的*佳敏捷实践的方法,书中介绍规则均来自Martin多年的经验,拥有很高的借鉴价值。
内容简介
计算机书籍
软件质量,不但依赖于架构及项目管理,而且与代码质量紧密相关。这一点,无论是敏捷开发流派还是传统开发流派,都不得不承认。.
本书提出一种观念:代码质量与其整洁度成正比。干净的代码,既在质量上较为可靠,也为后期维护、升级奠定了良好基础。作为编程领域的佼佼者,本书作者给出了一系列行之有效的整洁代码操作实践。这些实践在本书中体现为一条条规则(或称“启示”),并辅以来自现实项目的正、反两面的范例。只要遵循这些规则,就能编写出干净的代码,从而有效提升代码质量。..
本书阅读对象为一切有志于改善代码质量的程序员及技术经理。书中介绍的规则均来自作者多年的实践经验,涵盖从命名到重构的多个编程方面,虽为一“家”之言,然诚有可资借鉴的价值。...
作译者
Robert C. Martin,是软件工程领域的大师级人物,是《敏捷软件开发:原则、模式与实践》、《敏捷软件开发:原则、模式与实践(C#版)》(邮电)、《极限编程实践》(邮电)等国内引进的畅销书的作者,其中第一本原著荣获美国《软件开发》第13届震憾(Jolt)大奖,Martin的敏捷系列书是软件工程界的权威书籍。
韩磊,互联网产品与运营专家,技术书籍著译者。曾在全球著名的IT中文社区CSDN及《程序员》杂志任副总经理、总编辑等职。现居广州。译著有《梦断代码》和《C#编程风格》。与刘韧合著《网络媒体教程》,与戴飞合译《BeginningC#Objects中文版:概念到代码》。
目录
1.1 要有代码 2
1.2 糟糕的代码 2
1.3 混乱的代价 3
1.3.1 华丽新设计 4
1.3.2 态度 4
1.3.3 迷题 5
1.3.4 整洁代码的艺术 5
1.3.5 什么是整洁代码 6
1.4 思想流派 10
1.5 我们是作者 11
1.6 童子军军规 12
1.7 前传与原则 12
1.8 小结 12
1.9 文献 13
第2章 有意义的命名 15
2.1 介绍 15
2.2 名副其实 16
2.3 避免误导 17
2.4 做有意义的区分 18
译者序
2007年3月,我在SD West 2007技术大会上聆听了Robert C. Martin(鲍勃大叔)的主题演讲“Craftsmanship and the Problem of Productivity: Secrets for Going Fast without Making a Mess”。一身休闲打扮的鲍勃大叔,以一曲嘲笑低水平编码者的Code Monkey(代码猴子)开场。
是的,我们就是一群代码猴子,上蹿下跳,自以为领略了编程的真谛。可惜,当我们抓着几个酸桃子,得意洋洋坐到树枝上,却对自己造成的混乱熟视无睹。那堆“可以运行”的乱麻程序,就在我们的眼皮底下慢慢腐坏。
从听到那场以TDD为主题的演讲之后,我就一直关注鲍勃大叔,还有他在TDD和整洁代码方面的言论。去年,人民邮电出版社计算机分社拿一本书给我看,封面上赫然写着Robert C. Martin的大名。看完原书序和前言,我已经按捺不住,接下了翻译此书的任务。这本书名为Clean Code,乃是Object Mentor(鲍勃大叔开办的技术咨询和培训公司)一干大牛在编程方面的经验累积。按鲍勃大叔的话来说,就是“Object Mentor整洁代码派”的说明。
正如Coplien在序中所言,宏大建筑中最细小的部分,比如关不紧的门、有点儿没铺平的地板,甚至是凌乱的桌面,都会将整个大局的魅力毁灭殆尽。这就是整洁代码之所系。Coplien列举了许多谚语,证明整洁的价值,中国也有修身齐家治国平天下之语。整洁代码的重要性毋庸置疑,问题是如何写出真正整洁的代码。..
本书既是整洁代码的定义,亦是如何写出整洁代码的指南。鲍勃大叔认为,“写整洁代码,需要遵循大量的小技巧,贯彻刻苦习得的‘整洁感’。这种‘代码感’就是关键所在……它不仅让我们看到代码的优劣,还予我们以借戒规之力化劣为优的攻略。”作者阐述了在命名、函数、注释、代码格式、对象和数据结构、错误处理、边界问题、单元测试、类、系统、并发编程等方面如何做到整洁的经验与最佳实践。长期遵照这些经验编写代码,所谓“代码感”也就自然而然滋生出来。更有价值的部分是鲍勃大叔本人对3个Java项目的剖析与改进过程的实操记录。通过这多达3章的重构记录,鲍勃大叔充分地证明了童子军军规在编程领域同样适用:离开时要比发现时更整洁。为了向读者呈现代码的原始状态,这部分代码及本书其他部分的绝大多数代码注释都不做翻译。如果读者有任何疑问,可通过邮件与我沟通(cleancode.cn@gmail.com)。
接触开发技术十多年以来,特别是从事IT技术媒体工作六年以来,我见过许多对于代码整洁性缺乏足够重视的开发者。不算过分地说,这是职业素养与基本功的双重缺陷。我翻译The Elements of C# Style(中译版《C#编程风格》)和本书,实在也是希望在这方面看到开发者重视度和实际应用的提升。
在本书的结束语中,鲍勃大叔提到别人给他的一条腕带,上面的字样是Test Obsessed(沉迷测试)。鲍勃大叔“发现自己无法取下腕带。不仅是因为腕带很紧,而且那也是条精神上的紧箍咒。……它一直提醒我,我做了写出整洁代码的承诺。”有了这条腕带,代码猴子成了模范童子军。我想,每位开发者都需要这样一条腕带吧?...
韩 磊
2009年11月
前言
你的代码在哪道门后面?你的团队或公司在哪道门后面?为什么会在那里?只是一次普通的代码复查,还是产品面世后才发现一连串严重问题?我们是否在战战兢兢地调试自己之前错以为没问题的代码?客户是否在流失?经理们是否把我们盯得如芒刺在背?当事态变得严重起来,如何保证我们在那道正确的门后做补救工作?答案是:技艺(craftsmanship)。.
习艺之要有二:知和行。你应当习得有关原则、模式和实践的知识,穷尽应知之事,并且要对其了如指掌,通过刻苦实践掌握它。
我可以教你骑自行车的物理学原理。实际上,经典数学的表达方式相对而言确实简洁明了。重力、摩擦力、角动量、质心等,用一页写满方程式的纸就能说明白。有了这些方程式,我可以为你证明出骑车完全可行,而且还可以告诉你骑车所需的全部知识。即便如此,你在初次骑车时还是会跌倒在地。
编码亦同此理。我们可以写下整洁代码的所有“感觉良好”的原则,放手让你去干(换言之,让你从自行车上摔下来)。那样的话,我们算是哪门子老师?而你又会成为怎样的学生呢?
不!本书可不会这么做。
学写整洁代码很难。它可不止于要求你掌握原则和模式。你得在这上面花工夫。你须自行实践,且体验自己的失败。你须观察他人的实践与失败。你须看看别人是怎样蹒跚学步,再转头研究他们的路数。你须看看别人是如何绞尽脑汁做出决策,又是如何为错误决策付出代价。
阅读本书要多用心思。这可不是那种降落前就能读完的“感觉不错”的飞机书。本书要让你用功,而且是非常用功。如何用功?阅读代码—大量代码。而且你要去琢磨某段代码好在什么地方、坏在什么地方。在我们分解,而后组合模块时,你得亦步亦趋地跟上。这得花些工夫,不过值得一试。
本书大致可分为3个部分。前几章介绍编写整洁代码的原则、模式和实践。这部分有相当多的示例代码,读起来颇具挑战性。读完这几章,就为阅读第2部分做好了准备。如果你就此止步,只能祝你好运啦!..
第2部分最需要花工夫。这部分包括几个复杂性不断增加的案例研究。每个案例都清理一些代码—把有问题的代码转化为问题少一些的代码。这部分极为详细。你的思维要在讲解和代码段之间跳来跳去。你得分析和理解那些代码,琢磨每次修改的来龙去脉。
你付出的劳动将在第3部分得到回报。这部分只有一章,列出从上述案例研究中得到的启示和灵感。在遍览和清理案例中的代码时,我们把每个操作理由记录为一种启示或灵感。我们尝试去理解自己对阅读和修改代码的反应,尽力了解为什么会有这样的感受、为什么会如此行事。结果得到了一套描述在编写、阅读、清理代码时思维方式的知识库。
如果你在阅读第2部分的案例研究时没有好好用功,那么这套知识库对你来说可能所值无几。在这些案例研究中,每次修改都仔细注明了相关启示的标号。这些标号用方括号标出,如:[H22]。由此你可以看到这些启示在何种环境下被应用和编写。启示本身不值钱,启示与案例研究中清理代码的具体决策之间的关系才有价值。
如果你跳过案例研究部分,只阅读了第1部分和第3部分,那就不过是又看了一本关于写出好软件的“感觉不错”的书。但如果你肯花时间琢磨那些案例,亦步亦趋—站在作者的角度,迫使自己以作者的思维路径考虑问题,就能更深刻地理解这些原则、模式、实践和启示。这样的话,就像一个熟练地掌握了骑车的技术后,自行车就如同其身体的延伸部分那样;对你来说,本书所介绍的整洁代码的原则、模式、实践和启示就成为了本身具有的技艺,而不再是“感觉不错”的知识。
致谢
插图
感谢两位艺术家Jennifer Kohnke和Angela Brooks。Jennifer绘制了每章起始处创意新颖、效果惊人的插图,以及Kent Beck、Ward Cunningham、Bjarne Stroustrup、Ron Jeffries、Grady Booch、Dave Thomas、Michael Feathers和我本人的肖像。
Angela绘制了文中那些精致的插图。这些年她为我画了一些画,包括Agile Software Development: Principles, Patterns, and Practices(中译版《敏捷软件开发:原则、模式与实践》)一书中的大量插图。她是我的长女,常给我带来极大的愉悦。...
序言
rlighed i sm ting er ikke nogen lille ting.
“小处诚实非小事。”这句话正好是我想在这里说的。以小见大。本书写到了一些价值殊胜的小主题。
神在细节之中,建筑师Ludwig mies van der Rohe(路德维希·密斯·范·德·罗) 如是说。这句话引发了有关软件开发、特别是敏捷软件开发中架构所处地位的若干争论。鲍勃(Bob) 和我时常发现自己沉湎于此类对话中。没错,Ludwig mies van der Rohe的确专注于效用和基于宏伟架构之上的永恒建筑形式。然而,他也为自己设计的每所房屋挑选每个门把手。为什么?因为小处见大。
就TDD 话题展开目前仍在继续的“辩论”时,鲍勃和我认识到,我们均同意软件架构在开发中占据重要地位,但就其确切意义而言,我们之间还有分歧。然而,这种矛与盾孰利的讨论相对而言并不重要,因为在项目开始之时,我们理所当然应该让专业人士投入些许时间去思考及规划。20世纪90年代末期有关仅以测试和代码驱动设计的概念已一去不返。相对于任何宏伟愿景,对细节的关注甚至是更为关键的专业性基础。首先,开发者通过小型实践获得可用于大型实践的技能和信用度。其次,宏大建筑中最细小的部分,比如关不紧的门、有点儿没铺平的地板,甚至是凌乱的桌面,都会将整个大局的魅力毁灭殆尽。这就是整洁代码之所系。
架构只是软件开发用到的借喻之一,主要用在那种等同于建筑师交付毛坯房一般交付初始软件产品的场合。在Scrum和敏捷(Agile)的日子里,人们关注的是快速将产品推向市场。我们要求工厂全速运转、生产软件。这就是人类工厂:懂思考、会感受的编码人,他们由产品备忘或用户故事开始创造产品。来自制造业的借喻在这种场合大行其道。例如,Scrum就从装配线式的日本汽车生产方式中获益良多。
即便是在汽车工业里,大量工作也并不在于生产而在于维护—或避免维护。对于软件而言,百分之八十或更多的工作量集中在我们美其名曰“维护”的事情上:其实就是修修补补。与其接受西方关于制造好软件的传统看法,不如将其看作建筑工业中的房屋修理工,或者汽车领域的汽修工。日本式管理对于这种事怎么说的呢?
大约在1951年,一种名为“全员生产维护”(Total Productive Maintenance,TPM)的质量保证手段在日本出现。它关注维护甚于关注生产。TPM的主要支柱之一是所谓的5S原则体系。5S是一套规程,用“规程”这个词,是为了读者便于理解。5S原则其实是精益(Lean)—西方视野中的一个时髦词,也是在软件领域渐领风骚的时髦词—的基石所在。正如鲍勃大叔(Uncle Bob)在前言中写到的,良好的软件实践遵循这些规程:专注、镇定和思考。这并非总只有关实作,有关推动工厂设备以最高速度运转。5S哲学包括以下概念:
整理(Seiri) ,或谓组织(想想英语中的sort(分类、排序)一词)。搞清楚事物之所在—通过恰当地命名之类的手段—至关重要。觉得命名标识无关紧要?读读后面的章节吧。
整顿(Seiton),或谓整齐(想想英文中的systematize(系统化)一词)。有句美国老话说:物皆有其位,而后物尽归其位(A place for everything, and everything in its place)。每段代码都该在你希望它所在的地方—如果不在那里,就需要重构了。
清楚(Seiso),或谓清洁(想想英文中的shine(锃亮)一词)。清理工作地的拉线、油污和边角废料。对于那种四处遗弃的带注释的代码及反映过往或期望的无注释代码,本书作者怎么说的来着?除之而后快。
清洁(Seiketsu),或谓标准化。有关如何保持工作地清洁的组内共识。本书有没有提到在开发组内使用一贯的代码风格和实践手段?这些标准从哪里来?读读看。..
身美(Shitsuke) ,或谓纪律(自律)。在实践中贯彻规程,并时时体现于个人工作上,而且要乐于改进。
如果你接受挑战—没错,就是挑战,阅读并应用本书,你就会理解和赞赏上述最后一条。我们最终是在驶向一种负责任的专业精神之根源所在,这种专业性隶属于一个关注产品生命周期的专业领域。在我们遵循TPM来维护机动车和其他机械时,停机维护—等待缺陷显现出来—并不常见。我们更上一层楼:每天检查机械,在磨损机件停止工作之前就换掉它,或者按常例每1000英里(约1609.3km)就更换润滑油、防止磨损和开裂。对于代码,应无情地做重构。还可以更进一步,就像TPM运动在50多年前的创新:一开始就打造更易维护的机械。写出可读的代码,重要程度不亚于写出可执行的代码。1960年左右,围绕TPM引入的终极实践(ultimate practice),关注用全新机械替代旧机械。诚如Fred Brooks所言,我们或许应该每7年就重做一次软件的主要模块,清理缓慢陈腐的代码。也许我们该把重构周期从以年计缩短到以周、以天甚至以小时计。那便是细节所在了。
细节中自有天地,而在生活中应用此类手段时也有微言大义,就像我们一成不变地对那些源自日本的做法寄予厚望一般。这并非只是东方的生活观;英美民间也遍是这类警句。上引“整顿”(Seiton)二字就曾出现在某位俄亥俄州牧师的笔下,他把齐整看作是“荡涤种种罪恶之良方”。“清楚”(Seiso)又如何呢?整洁近乎虔诚(Cleanliness is next to godliness)。一张脏乱的桌子足以夺去一所丽宅的光彩。老话怎么说“身美”(Shitsuke)的?守小节者不亏大节(He who is faithful in little is faithful in much)。对于时时准备在恰当时机做重构,为未来的“大”决定夯实基础,而不是置诸脑后,有什么说法吗?及时一针省九针(A stitch in time saves nine)。早起的鸟儿有虫吃(The early bird catches the worm)。日事日毕(Don’t put off until tomorrow what you can do today)。在精益实践落入软件咨询师之手前,这就是其所谓“最后时机”的本义所在。摆正单项工作在整体中的位置呢?巨木生于树籽(Mighty oaks from little acorns grow)。如何在日常生活中做好简单的防备性工作呢?防病好过治病(An ounce of prevention is worth a pound of cure)。一天一苹果,医生远离我(An apple a day keeps the doctor away)。整洁代码以其对细节的关注,荣耀了深埋于我们现有、或曾有、或该有的壮丽文化之下的智慧根源。
即便是在宏伟的建筑作品中,我们也听到关注细节的回响。想想Ludwig mies van der Rohe的门把手吧。那正是整理(seiri)。认真对待每个变量名。你当用为自己第一个孩子命名般的谨慎来给变量命名。
正如每位房主所知,此类照料和修葺永无休止。建筑师Christopher Alexander—模式与模式语言之父—把每个设计动作看作是较小的局部修复动作。他认为,设计良好结构才是建筑师的本职所在,而更大的建筑形态则当留给模式及居住者搬进的家私来完成。设计始终在持续进行,不只是在新建一个房间时,也在我们重新粉刷墙面、更换旧地毯或者换厨房水槽时。大多数艺术门类也持类似主张。在寻找其他推崇细节的人时,我们发现,19世纪法国作家Gustav Flaubert(古斯塔夫·福楼拜)名列其中。法国诗人Paul Valery(保尔·瓦雷里)认为,每首诗歌都无写完之时,得持续重写,直至放弃为止。全心倾注于细节,屡见于追求卓越的行为之中。虽然这无甚新意,但阅读本书对读者仍是一种挑战,你要重拾久已弃置脑后的良好规则,自发自主,“响应改变”。
不幸的是,我们往往见不到人们把对细节的关注当作编程艺术的基础要件。我们过早地放弃了在代码上的工作,并不是因为它业已完成,而是因为我们的价值体系关注外在表现甚于关注要交付之物的本质。疏忽最终结出了恶果:坏东西一再出现。无论是在行业里还是学术领域,研究者都很重视代码的整洁问题。供职于贝尔软件生产研究实验室(Bell Labs Software Production Research)—没错,就是生产!—时,我们有些不太严密的发现,认为前后一致的缩进风格明显标志了较低的缺陷率。我们原指望将质量归因于架构、编程语言或者其他高级概念;我们的专业能力归功于对工具的掌握和各种高高在上的设计方法,至于那些安置于厂区的机器,那些编码者,他们居然通过简单地保持一致缩进风格创造了价值,这简直是一种侮辱。我在17年前就在书中写过,这种风格远不止是一种单纯的能力那么简单。日本式的世界观深知日常工作者的价值,而且,还深知工作者简单的日常行为所锻造的开发系统的价值。质量是上百万次全心投入的结果—而非仅归功于任何来自天堂的伟大方法。这些行为简单却不简陋,也不意味着简易。相反,它们是人力所能达的不仅伟大而且美丽的造物。忽略它们,就不成其为完整的人。
当然,我仍然提倡放宽思路,也推崇根植于深厚领域知识和软件可用性的各种架构手法的价值。但本书与此无关—至少,没有明显关系。本书精妙之处,其意义之深远,不该无人赏识。它正与Peter Sommerlad、Kevlin Henny及Giovanni Asproni等真正写代码的人现今所持的观念相吻合。他们鼓吹“代码即设计”和“简单代码”。我们要谨记,界面就是程序,而且其结构也极大地反映出程序结构,但也理应始终谦逊地承认设计存在于代码中,这至关紧要。制造上的返工导致成本上升,但重做设计却创造出价值。我们应当视代码为设计—作为过程而非终点的设计—这种高尚行为的漂亮体现。耦合与内聚的架构韵律在代码中脉动。Larry Constantine以代码的形式—而不是用UML那种高高在上的抽象概念—来描述耦合与内聚。Richard Garbriel在“Abstraction Descant”(抽象刍议)一文中告诉我们,抽象即恶。代码除恶,而整洁的代码则大抵是圣洁的。
回到我那个小小的乐嚼包装盒,我想要重点提一下,那句丹麦谚语不只是教我们重视小处,更教我们小处要诚实。这意味着对代码诚实、对同僚坦承代码现状,最重要的是在代码问题上不自欺。是否已尽全力“把露营地清理得比来时还干净”?签入代码前是否已做重构?这可不是皮毛小事,它正高卧于敏捷价值的正中位置。Scrum有一种建议的实践,主张重构是“完成”(Done)概念的一部分。无论是架构还是代码都不强求完美,只求竭诚尽力而已。人孰无过,神亦容之(To err is human; to forgive, divine)。在Scrum中,我们使一切可见。我们晾出脏衣服。我们坦承代码状态,因为它永不完美。我们日渐成为完整的人,配得起神的眷顾,也越来越接近细节中的伟大之处。
媒体评论
——C++语言之父Bjarne Stroustrup
如果代码让编程语言看起来像是专为解决那个问题而存在的,就可以称为漂亮的代码。
——Ward Cunningham,Wiki发明者,极限编程创始人之一
整洁的代码总是看起来像是某位特别在意它的人写的,几乎没有改进的余地。
——Michael Feathers,
Working Effectively with Legacy Code(中译版《修改代码的艺术》的作者减少重复代码,提高表达力,提早构建简单抽象。这就是我写整洁代码的方法。..
——Ron Jeffries,
Extreme Programming Installed(中译版《极限编程实施》)的作者
毫无疑问,Robert C.Martin的名字就是最好的质量保证,他的每一本书都使程序员在编程思想层面有新的提升。而且我相信韩磊历时一年的翻译也会成为本书成功中文化的关键因素。如果你真正按照书上提供的“规则”去做的话,它足以节省你50%的code时间。
——段钢(kanxue)
看雪安全论坛站长
代码的整洁往往是很多程序员既明白又装不明白的事情,代码是有生命的,他的生命是程序员赋予的,如果你不好好规划设计编写他,他也会像一颗歪脖子树那样生长,难以成才,而且形象大丧,作为一个程序员,如果你有理想,有目标,那么让你的代码也整洁起来,看看这本书,韩磊恰到好处的翻译,会让你明了这些。...
——青润
独立软件咨询师
书摘
过去30年以来,以下建议以不同形式一再出现:函数应该做一件事。做好这件事。只做这一件事。
问题在于很难知道那件该做的事是什么。
代码清单3.3只做了一件事,对吧?其实也很容易看作是三件事:(1)判断是否为测试页面;(2)如果是,则容纳进设置和分拆步骤;(3)渲染成HTML。如果函数只是做了该函数名下同一抽象层上的步骤,则函数还是只做了一件事。
编写函数毕竟是为了把大一些的概念(换言之,函数的名称)拆分为另一抽象层上的一系列步骤。
代码清单3.1明显包括了处于多个不同抽象层级的步骤。显然,它所做的不止一件事。即便是代码清单3-2也有两个抽象层,这已被我们将其缩短的能力所证明。然而,很难再将代码清单3.3做有意义的缩短。可以将if语句拆出来做一个名为include Setup And Teardonws Ifrestpage的函数,但那只是重新诠释代码,并未改变抽象层级。
所以,要判断函数是否不止做了一件事,还有一个方法,就是看是否能再拆出一个函数,该函数不仅只是单纯地重新诠释其实现。