基本信息
- 原书名:The Clean Coder:A Code of Conduct for Professional Programmers
- 原出版社: Prentice Hall; 1 edition
编辑推荐
世界级软件开发大师Robert C. Martin谈职业素养
编程大师bob 大叔40 余年编程生涯的心得体会
内容简介
作译者
译者简介:
章显洲,阿里巴巴高级技术专家,敏捷与精益方法实践者,专注于敏捷与精益管理,擅长互联网研发团队的构建与改善。业余以技术翻译作为个人修炼与回馈软件开发社区的途径。自2009年来,翻译和合译的技术书籍包含《精益软件开发艺术》、《微软的秘密》、《软件架构师应该知道的97件事》、《程序员的职业素养》、《看板》。偶尔也会出现在技术社区的聚会上作一些分享和演讲。
余晟,毕业于东北师范大学计算机系,副修中文,非正统型技术爱好者。曾任抓虾网、银杏泰克主力程序员,盛大创新院高级研究员,现任华南某电商公司技术总监。坚信计算机可以无限延伸人的能力,前提是人必须理解计算机的逻辑,所以对任何技术都不应该浅尝辄止,仅仅满足于“会用”。
目录
第1章 专业主义 1
1.1 清楚你要什么 2
1.2 担当责任 2
1.3 首先,不行损害之事 4
1.3.1 不要破坏软件功能 4
1.3.2 不要破坏结构 7
1.4 职业道德 8
1.4.1 了解你的领域 10
1.4.2 坚持学习 11
1.4.3 练习 11
1.4.4 合作 12
1.4.5 辅导 12
1.4.6 了解业务领域 13
1.4.7 与雇主/客户保持一致 13
1.4.8 谦逊 13
1.5 参考文献 14
第2章 说“不” 15
2.1 对抗角色 17
2.2 高风险时刻 20
译者序
我在招聘时常问的一个问题是:在你过去的工作中,遭遇过哪些印象深刻的困难,最后是怎么解决的?依我的经验,简历写得再漂亮的人,如果这个问题答不好,大都可以直接忽略。为什么会有这种结论?因为我们需要招聘的不是“经历丰富”的人,而是“有职业素养的人”。你遇到的问题可能很容易也可能很难,但我看重的并不是问题的难度,而是解决问题的方式、步骤以及反思的深度。拿恢复误删数据来说,这可能算非常简单的任务。我更感兴趣的是怎样分析问题,找了怎样的资料,采取了怎样的步骤,此后做了哪些措施来避免这种错误再次出现。在我看来,相比问题本身的难度,解决问题的方式和步骤以及反思的深度,都体现出一个人的职业素养。
是的,上面我两次提到了“职业素养”。相比起“专业主义”、“职业化”等说法,我更喜欢用它来翻译Professionalism,因为素养强调的并不是天赋的神秘,也不是技艺的高深,而是持续积淀的结晶:一方面,它体现了能力和素质;另一方面,它又强调了持续的积累和养成。作为职业开发人员,基本技能不够熟练,当然谈不上职业素养。但是能迅速地编写代码,却不关心代码背后的意义,不能迅速判断、解决程序运行中的各种问题,不能自信满满地为自己交付的程序承担责任,同样是与职业素养绝缘的——许多所谓的“高手”,其实正是缺乏职业素养的典型。
当然,这只是我对于“职业素养”的理解。由个体经验总结的“职业素养”,多有一鳞半爪的嫌疑,所以即便你觉得上面说的有道理,难免感觉只见树木,不见森林。其实真正的“职业素养”绝不限于上述几方面,而是要广阔得多,深刻得多。要想一窥技术人员“职业素养”的全貌,已经有很多现成的资料可以参考,本书就是其中的佼佼者。
作为一本技术类书籍,本书中有相当的内容是介绍纯技艺的方面,比如测试驱动开发等,自认已经算“职业开发人员”的人,大概对此并不感冒(不过,我仍然建议你认真看看)。但其他的内容,绝对值得你感冒,比如:什么情况下应该对业务部门说“是”,说“是”意味着什么。如果你没有想过这些问题,或者没有明确的答案,不妨看看Bob大叔是怎么说的:
(说“是”时)你对自己将会做某件事做了清晰的事实陈述,而且还明确说明了完成期限。那不是指别人,而是指你自己。你谈的是自己会去做的一项行动,而且,你不是“可能”去做,或是“可能做到”,而是“会”做到。
就我所见,技术人员往往太容易说“是”,往往在没有明确目标和期限的情况下,就草率给出了确认的答复,而且并不将其视为自己的一种承诺。屡见不鲜的项目延期,有相当原因就是在这种不负责任的情况下说“是”所致。但是我们想想,似乎没有哪一个正经行业,会把不能完成任务的人视为“有职业素养的人”,软件行业也不能例外。
如果你觉得自己已经足够负责,懂得“是”背后所蕴含的意义和责任,也不过如此,我们不妨更进一步,看看关于说“否”。在第2章,Bob大叔介绍了两个项目搞砸的经过。他并没有像常见的所谓专家那样故作聪明地指出实施过程中出现了哪些问题,导致了失败,而是一针见血地指出:这两个项目之所以会搞砸,因为开发人员没有坚决抵制各种不专业的需求(比如一些无关紧要但成本巨大的需求),抵制各种不专业的行为(比如为了赶工期而降低对程序质量的要求),最终只好喝下自己酿出的苦酒。对此,Bob大叔总结道:
有时候,获取正确决策的唯一途径,便是勇敢无畏地说出“不”字……我们要明白,委屈专业原则以求全,并非问题的解决之道。舍弃这些原则,只会制造出更多的麻烦……
对我来说,这真是振聋发聩的号角。而且,这种思维,这种视角,其实是许多技术人员所不屑或者不愿面对的——最初我也这么认为,但尝试在工作中主动说了几次“不”之后,我逐渐发现:花三分的力气去抵制无理的需求,可以节省十分甚至二十分的开发时间;相反,自欺欺人地说服自己凑合接受了无理需求,往往会非常被动乃至无法脱身,到最后,项目就落得著名的IBM OS/360操作系统的下场,越挣扎,巨兽在泥潭中就陷得越深。
要学习这样的道理,当然也可以参加培训班,听取授课或者阅读讲义,但那未免太显正经而缺乏亲和力。Bob大叔的特别之处在于,他总是可以通过浅显易懂的故事,清晰而敏锐地揭示问题的核心所在。其中许多故事正是他自己亲身经历的,阅读过程中常会会心一笑,因为遇到了开发人员都懂的妙趣,比如费尽全力也是徒劳,无法让其他人理解“编辑程序的程序”。笑过之后,又会认识到许多道理——无法让其他人理解“编辑程序的程序”并不是真正的原因,真正的原因是:“客户……对功能的设想,其实经不起电脑前真刀真枪的考验……问题在于,东西画在纸上与真正做出来,是不一样的。业务方看到真正的运行情况时就会意识到,自己想要的根本不是这样。一看到已经满足的需求,关于到底要什么,他们就会冒出更好的想法——通常并不是他们当时看到的样子……真正的解决办法,是约定共同认可的验收测试标准,并在开发过程中保持沟通。”至少就我的经验,这一点是说得非常对的。我曾经尝试在与业务部门确定目标原型之后,要求对方指派一个负责人。在IT部坐班,负责协商、跟进整个开发流程,确认每一点修改。这样既保证最终结果符合业务部门的需求,又提高了开发人员的工作效率,综合来看,成效非常显著。
类似的例子还有很多,在阅读这本书时,我经常会惋惜:如果早一点读到这本书,或许我之前就不会犯这样那样的错误,就能更早更好地积累自己的职业素养。况且能有妙趣横生的书讲述看似枯燥的“职业素养”,对读者来说,又是一种幸运。德国作家托玛斯·曼曾经津津乐道于“斜躺在沙发上整天阅读叔本华”的美妙感觉,那是因为叔本华的文笔优美、流畅,可以把哲学变为惬意的享受。作为同时读过叔本华和Bob大叔的人,我想说,斜躺在沙发上整天阅读《程序员的职业素养》,认识和了解开发人员的职业素养,同样是相当惬意的享受。
余晟
广东,2012/7/18
负阴抱阳,知行合一
“师者,所以传道授业解惑也。”Robert C. Martin,软件开发社区中亲切地称他为Bob大叔,正是这样一位明师。
2003年,他的《敏捷软件开发:原则、模式与实践》(下称ASD)在国内上市。我那时进入软件开发行业刚刚一两年,这本书真可谓是及时雨。在精读全书和细心对照书中案例练习后,我感觉自己在面向对象设计方面的功力有了比较明显的提升。那时因工作环境所限,身边没有能够手把手给予技术辅导的导师,因此,那时在我心中Bob大叔无疑就是一盏指路明灯。后来在网上找到了不少Bob大叔的演讲PPT,沿着链接,又找到了Object Mentor公司其他一些软件开发专家的演讲PPT和博客,我如饥似渴地阅读揣摩。现在回头想来,正是在这个阶段我开始建立起“编程技艺”的视角。
时间过得很快,转眼就到了2010年,不觉中我已在软件开发的多个领域工作了近10年。2010年,Bob大叔的《代码整洁之道》一上市,我马上给自己和项目团队订了好几本。在为ASD所写的序中,Bob大叔写道:“最好的软件开发人员都知道一个秘密:美的东西比丑的东西创建起来更廉价,也更快捷。构建、维护一个美的软件系统所花费的时间、金钱都要少于丑的系统。……美的系统是灵活、易于理解的,构建、维护它们就是一种快乐。”如果说ASD中更多的是OO设计思想和模式精髓的阐述,那么在《代码整洁之道》中,Bob大叔提供了更为详尽的微距视角,涉及“命名”、“函数”、“代码格式”、“异常处理”、“单元测试”等编码主题,巨细靡遗地向软件工匠们极力传授整洁编码的艺术,进一步向软件开发社区慷慨分享了他在探索“软件之美”旅途中的参证心得。
但是,细心的读者可以发现,在前述两本书中Bob大叔阐述的主体还是软件编码技术本身,作为一门技艺而言,止步于具体技术或曰“术”的层面,应该还未算得完整。后来,在YouTube、SlideShare和Object Mentor等站点上,我看见Bob大叔有不少演讲趋向于聚焦在编程主体即软件开发者自身行为模式和特质层面上,就猜到他不久应该就会有此方面的新著推出。Bob大叔就是Bob大叔,在探索和分享软件技艺的路上,他内心怀有对软件开发社区发展责无旁贷的使命感。果不其然,他将这些体悟浓缩在又一本新著上,这本书便是读者手上的这本《程序员的职业素养》。
本书阐述的是Bob大叔关于软件技艺主体的沉思,这些沉思并非是纯粹形而上的思辨推演,而是他对自身编程生涯的深刻反思和经验沉淀。在这本书中,Bob大叔并非是以高人一等的凌人盛气(事实上,他应该有这样的资格)大行说教,而是毫不掩饰自己在职业生涯中曾犯下的各种错误和不堪往事,以这些案例为载体,现身说法,娓娓道来使自己得以转变和提升的种种“机锋”,并留有意味深长的空间,供读者自己结合自身状况进一步体悟提炼,而非给出硬梆梆的一堆结论。这是何等的胸怀、格局和智慧!
前言
我也是程序员。我编了42年 的程序。这42年里,我什么都经历过。我被开除过,也被表扬过。我当过小组长,当过主管,也当过普通员工,甚至当过CEO。我的同事有聪明绝顶的,也有混日子的懒蛋 。我曾经开发过尖端的嵌入式软硬件系统,也写过寻常公司的工资系统。我用过COBOL、FORTRAN、BAL、PDP-8、PDP-11、C、C++、Java、Ruby、Smalltalk,还有其他许多语言和系统。我的同事有混工资的家伙,也包括无可挑剔的专业人士。本书要讲的,正是那些无可挑剔的专业人士。
在这本书里,我会尝试定义专业程序员。我会讲解,成为真正专业的程序员,需要什么样的态度、原则、行动。
这些态度、原则、行动从哪里得知?它们源于我一路走来的亲身体会。坦白说,看到我第一次作程序员时的表现,你几乎不会想到与“专业”二字搭边。
那是1969年,我17岁的时候。我父亲督促本地一家名为ASC的公司雇用我为兼职程序员。(是的,我父亲做得出这种事情。我曾见到他冲到疾驰的汽车前,伸出双臂大喊“停”,车真的就停下来了。没人敢对他说不。)那家公司把我扔在保管所有IBM电脑操作手册的房间里。我的任务就是把历年的更新记录到操作手册上。就是在那里,我第一次见到了“本页有意留空”这句话。
这个活干了好几天之后,我的上司让我写个简单的Easycoder 程序。领到这个任务可真叫人激动,我还从来没在真正的计算机上写过程序呢。不过,我曾钻研过Autocoder的说明书,对如何开始写这个程序,我也有些模糊的想法。
程序要做的就是,从磁带上读取记录,将旧的ID替换为新的ID。新的ID从1开始,逐个加1。然后,把更换了新ID的记录写到新的磁带上。
上司给我看了一个架子,上面堆着许多红色和蓝色的打孔卡片。想象一下,你买了50张纸牌,一半是红色的,一半是蓝色的,然后把它们一张张叠起来。那些打孔卡片就是这个样子的。总的来看它们红蓝相间,每部分颜色都包含了大概200张卡片。卡片的内容是所有程序员都会用到的子程序库的源代码。程序员通常会拿走堆在最上面的卡片,确认没拿错其他卡片,然后把卡片排在自己程序卡片的末尾。
我自己的程序写在编码表单上。编码表单是纸做的巨大的矩形列表,有25行,80列。每一行对应一张卡片。程序用大写字母和2号铅笔填在编码表单上。每行的最后6列,用2号铅笔编上号。通常编号以10为基础递增,这样将来还可以插入卡片。
填完编码表单,就要交给负责打孔的人。这家公司有几十名女员工,她们从一个大公文框中取出编码表单,然后把这些表单“打”到打孔机上。打孔机很像打字机,不过字符是打在卡片上的,而不是纸上。
过一天,负责纸带打孔的人会把对应的纸带通过办公交流信件发回给我。我那一小堆的打孔卡片,用我的编码表单包起来,外面用橡皮筋捆上。我想看看哪些卡片有打孔问题,但没有发现。所以我拿了一张子程序库的卡片,附加在我的程序卡片末尾,上楼交给电脑操作员。
计算机安放在密封的房间,有锁闭的大门,有高出地面的地板(用来走线)。我敲了门,操作员一脸严肃地拿走我那堆卡片,放在计算机房的另一个公文框内。等他们有空的时候,就会运行我的程序。
第二天,我拿回了自己的卡片。卡片外面裹着运行结果详单,用另一根橡皮筋捆起来(那时候我们得用很多橡皮筋)。
我翻开结果详单,发现编译失败了。详单里的出错消息我压根看不懂,所以我去找了上司。他仔细看了看,叽叽咕咕地说了几句,在上面做了个记号,然后拿起我的卡片,告诉我跟他走。
上司带我去了打孔室,找了一台没人用的打孔机。他逐个纠正了程序卡片上的错误,又加上了一两张卡片。他简单地介绍自己在做什么,但我根本来不及弄明白。
他把新的卡片带到计算机房,然后敲了门。他对操作员说了几句神秘的话,便跟在操作员身后进入了机房,还招手示意我跟上去。我们看着操作员开动磁带存储器,读入纸带。磁带旋转起来,打印机哒哒响起来,然后便结束了,程序运行正常了。
又过了一天,我的上司对我表示了感谢,告诉我以后不用来了。显然,ASC认为他们没时间去教一个17岁的孩子写程序。
但是我和ASC却没有就此断了关系。过了几个月,我得到了一份全职的工作(虽然是三班倒的第二班),管理ASC的离线打印机。这些打印机以磁带上存储的图片为材料,印刷垃圾邮件。我的任务是给打印机装纸,给磁带机装磁带,解决卡纸问题,除此之外,就是盯着机器运行。
那是1970年,我上不了大学,也不想上大学。越南战争还打得热闹,学校里一片喧嚣。我一直如饥似渴地学习使用COBOL、FORTRAN、PL/1、PDP-8、
IBM 360汇编语言。我的想法是不去上大学,自学成材,尽自己的力量去找份编程的工作。
序言
事情是这样的:不久以前,在不远的地方。来,背景、灯光、摄像、演员,一切就绪,那我就开讲了……
几年前,我在一家中等规模的公司工作,公司销售的是政府严格管制的产品。这类公司你肯定知道:办公场所位于一幢三层小楼里,我们坐的是格子间,总监级以上人物则可以拥有私人办公室;把相关人员召集到会议室里开个会,可能得花一个星期左右的时间。
我们所在的市场竞争非常激烈。这时,政府放开了一个新产品。
突然间我们拥有了一批全新的潜在客户,我们所要做的就是让他们购买我们的产品。这意味着必须在某个截止日期前向联邦政府提出申请,在另一个截止日期前通过评估审计,并在第三个截止日期前完成交付。
管理层一遍又一遍地向我们强调这些截止日期的重要性。如果延期一次,政府就会把我们列进当年的黑名单;而如果客户们没有在第一时间和我们签约,他们全部就会和别的供应商签。如果拿不到订单,我们就彻底出局了。
在这种环境下,有些人会抱怨,有些人则会说:“艰难困苦,玉汝于成。”
我那时是从开发部门晋升上来负责技术方面工作的项目经理。我的职责是确保网站按期上线,这样潜在客户便可以从网站上下载资料,其中最重要的资料是注册表单。负责业务方面的项目经理是我的搭档,我叫他Joe。Joe的工作职责是销售、做市场推广和分析非技术性需求。这位老兄平素也挺喜欢用“艰难困苦,玉汝于成”这样的调调说事。
如果你在美国公司工作过,肯定知道指责、过失追究和工作厌恶症都是司空见惯的。不过在我们公司里,Joe和我有个十分有效的办法来解决这类问题。
我们这对搭档有点儿像蝙蝠侠与罗宾,任务就是要把事情搞定。我每天都会和技术团队会面;我们每一天都会调整计划,找到关键路径,扫除在关键路径上所有可能出现的障碍。如果有人需要什么软件,我们就去弄来。如果有人一边抱怨“天哪,我该吃午饭了”一边说自己更“喜欢”配置防火墙,我们就会给他们带午餐。如果有人想去搞定配置问题,但手上还有其他更重要的事项要去处理,Joe和我便会去找他的主管协调。
如果不行,就去找经理。
再不行,就去找总监。
总之,肯定会把事情搞定。
如果说我们常常大动肝火、踢翻椅子、以大吼大叫的方式来沟通,这可能有点儿夸张了,但我们确实使尽了浑身解数来搞定遇到的每件事情,并且发明了一些新方法。但是,至今为止,让我引以自豪的是,我们并没有违背职业道德,没有为达目的不择手段。
我认为自己是团队的一员,而非凌驾于团队之上、只会中途插进去写一句SQL语句或做点儿结对编程写一两句代码的那种人。当时,我也是如此看待Joe的,认为他也是团队成员之一,而不是凌架于团队上,置身事外。
后来我才明白,Joe自己并不是这么看的。对我来说,这是令人很郁闷的一天。
那是个星期五下午的一点钟,下周一一早,网站就要按计划上线了。
完工了。*DONE*。每个系统都已就绪,我们已经准备好了。我把整个技术团队召集在一起,召开最后一次Scrum会议,准备上线。与会的不只是技术团队,还有市场营销、产品负责人这些业务人员。
我们感到十分自豪。这真是个美妙的时刻。
这时,Joe进来了。
媒体评论
—— Markus G·rtner,it-agile公司资深软件开发者
“有一些技术书颇具启发和教益,有一些则读来轻松喜悦且富有趣味,但很少有技术书籍能够同时兼具所有这四个特色。我感觉Martin所有的书都可归入此列。本书也不例外。 阅读、学习和守持书中的教诲,你将可以信心满满地把自己训练为软件专业人士。”
——George Bullock,微软公司资深程序经理
“如果计算机科学学位要求有‘毕业后必读书单’,本书当在其列。在现实的职业生涯中,糟糕的代码不会因学期结束就此消失,程序员也不会因加班加点开夜车编码便可获得A级评分,而雪上加霜的是,你还必须抽出精力与人打交道。就算你是个编程高手,也并不一定就可以称为专业人士。本书描述了迈向专业程序员的修炼旅程……而且阅读起来确实异常有趣。”
——Jeff Overvey,伊利诺伊大学厄本那-香槟分校
“本书远不只是给出了一套规则或指导方针,它还包含了无数来之不易的智慧和知识,这些宝贵财富通常只有经历过多年的试错,历经由初级学徒修炼成为大师级工匠的整个过程才能获得。如果你期望自己能成为软件专业人士,那么本书不容错过。”
——R.L. Bogetti·,Baxter Healthcare公司系统主设计师
书摘
专业主义
“噢,笑吧,科廷,老伙计。这是上帝,或者也可以说是命运或自然,跟我们开的一个玩笑。不过,不管这家伙是谁或是什么,他真幽默!哈哈!”
——?霍华德,《碧血金沙》
这么说,你确实是想成为一名专业的软件工程师,对吧?你希望能昂首挺胸向世界宣告“我是专业人士”,希望人们充满敬意地注视着你,对你礼遇有加。希望母亲们会指着你告诉自己的孩子要成为像你这样的人。这些都是你想要的,对吧?
1.1清楚你要什么
“专业主义”有很深的含义,它不但象征着荣誉与骄傲,而且明确意味着责任与义务。这两者密切相关,因为从你无法负责的事情上不可能获得荣誉与骄傲。
做个非专业人士可轻松多了。非专业人士不需要为自己所做的工作负责,他们大可把责任推给雇主。如果非专业人士把事情搞砸了,收拾摊子的往往是雇主;而专业人士如果犯了错,只好自己收拾残局。
如果你不小心放过了某个模块里的一个bug,以致公司损失了1万美元,结果将会怎样呢?非专业人士会耸耸肩说:“状况总是难免的嘛。”然后像没事儿人一样继续写下一个模块。而专业人士会自己为公司的那1万美元买单 !
哇,自掏腰包?那可真让人心疼唉!但专业人士就必须这么做。实际上,专业主义的精髓就在于将公司利益视同个人利益。看到了吧,“专业主义”就意味着担当责任。
1.2担当责任
想必你读过前面的引言了,对吧?如果没有,赶紧翻回去读一遍,因为本书将要讲的内容,都在其营造的语境里展开。
我曾因不负责任尝尽了苦头,所以明白尽职尽责的重要意义。
那是1979年,当时我是一家叫Teradyne的公司的“负责工程师”,所负责的软件控制着一个测量电话线路质量的小型机系统和微机系统,该系统的中央小型机通过带宽为300波特的拨号电话线与几十台控制测量硬件的外围微机连接在一起,程序是用汇编语言编写的。
我们的客户是各大电话公司的客服经理,他们每个人都负责10万条甚至更多的电话线路。我的系统负责帮助这些服务区经理抢在客户之前发现各种线路故障并及时修复。这可以减少客户投诉率,以免对此做监测的公共设施委员会相应下调电话公司收取的服务费。简单地说,这些系统极其重要。
每天晚上,这些系统都会运行“夜间例行程序”,即中央小型机会通知外围微机对所控制的电话线路进行检测;每天早上,中央计算机就能获取故障线路清单及其故障特征。根据这些报告,各服务区经理会安排人员修复故障,这样就不会有客户投诉了。
一次,我对几十个客户推出了一版新发布。“推出”这词可真是形象啊。我把软件写在磁带上,就把这些带子“推出”给客户了。客户载入这些磁带,然后重启系统。
这一新发布修复了几个小故障,还增加了客户要求的一项新功能。之前我们曾承诺会在截止日期之前提供那项新功能。我连夜赶工,总算在约定日期前交付了磁带。
两天后,我接到现场服务经理Tom的电话,他告诉我已经有好几个客户投诉“夜间例行程序”没能执行完成,他们没收到任何报告。我不由心头一沉:为了按时交付软件,我没测试“例程”。我测试了系统的其他大部分功能,但测试“例程”要费好几个小时,而当时我又必须交付软件。因为故障修复部分都不涉及“例程”部分的编码,所以我也没担心会有什么不妥。
收不到夜间报告,问题可就大了。修理工们会一时无事可忙但随后又要超负荷工作,而且,有些电话客户也可能会在这期间发现故障并投诉。要是弄丢一晚的数据,某一服务区经理肯定会打电话臭骂Tom。