驯服烂代码:在编程操练中悟道.html.pdf
《驯服烂代码:在编程操练中悟道.html.pdf》由会员分享,可在线阅读,更多相关《驯服烂代码:在编程操练中悟道.html.pdf(108页珍藏版)》请在三一文库上搜索。
1、序 极限编程的创始人Kent Beck对编程给出了如下定义: 1)编程是一种态度。 2)编程是一种技艺。 3)编程是一种习惯。 这三句话的语序并非随意排列,而是代表了一个渐进的过程。首先需要树立正确的编程态度,进而追求编程技艺的提升,最终形成良好的编程习惯。 正所谓“态度决定一切”,编程态度的重要性不言而喻,殊不知,作为程序员的我们却常常忽略了它。不是轻视,而是自以为已经理解。写出好代码,不是自然而然的吗?哪里用得着再三强调? 只是 只是他们会说:“倘若时间允许,我当然是要竭尽所能写出好代码啊!” 言外之意,若是时间不允许,我们就有了粗制滥造的权利了! 倘若不是编码,而是修建一栋大厦,难道建筑
2、工人可以说:“倘若时间允许,我当然要建造出牢固抗震的大厦啊!” 言外之意,若是时间不允许,我们就可以放宽大厦的质量了! 时间,何其无辜! 真正的编码态度,就是要在任何时刻都要保持精益求精,务求代码的正确无误,务求代码的清晰可读。一旦嗅到代码的“坏味道”,我们就应该及时重构。对于烂代码,我们就应该尽力去驯服!窃认 为,这或许才是伍斌写作本书的初衷:贯以正确的编程态度,进而提升编码技艺。 软件架构的重要性不言自明,开发团队也舍得花大量的成本在架构上追求最好。对于如何编写出好的代码,虽有诸如Martin Fowler、Robert C.Martin、Michael C.Feathers等大师珠玉在前
3、,为我们 编写出好代码提供了良好的模板,但是现状却是大量的烂代码俯拾皆是,而且层出不穷,并随着项目的演进而蔓延,以至于酿成不可挽回之势。究其原因,还是在一开始就没有对烂代码给予足够的重视, 为了赶进度,我们只追求功能的实现,满足一时之需求。我们忘记了地面的坎坷,忘记了沼泽的泥泞,刻意编织了一个美好的幻梦,致使我们忘记当下,只顾着远望前方,以至于越陷越深而不自觉。当我 们泥足深陷而不可自拔时,才发现这些烂代码已经不是我们目前的能力所能够应对的了。悔之晚矣! 态度是第一位的。如果我们从一开始就学会小步前行,并保证步伐的稳健,即使路况堪忧,也未必会泥足深陷。若是必须在泥沼之上行走,我们也可以找来木板
4、竹排,减轻身陷其中的压力。对于程序 员来说,驯服烂代码,其实就是我们谋生的技能,就是行走泥沼必备的木板竹排。因此,操练编码能力,提升自己的谋生技能,不过是题中应有之义。既然庖丁可以将解牛作成一门艺术,我们自然也不能 为写出勉强可用的代码而自满自足。 伍斌的这本大作得自他自己年复一年对代码的操练,真正体会了“练习中的平凡与伟大”,从而将测试驱动开发、重构与设计模式应用娴熟,达到得心应手的程度。本书就是伍斌日常的训练宝典,实 战笔录。作为编程操练社区bjdp.org1的创始人,伍斌几乎将全部身心都投入到IT社区公益中,为程序员提升编码技能布道传法,孜孜不倦,这令我钦佩不已。如今大作得以付梓出版,也
5、算是IT社区的幸 事。毕竟编程操练社区囿于场地与人力的限制,无法普及到更多的程序员。因而,阅读本书的读者,完全可以照着书中的例子,来一次虚拟的编程道场,操练技艺,驯服烂代码,不亦乐乎。 陆放翁诗云“纸上得来终觉浅,绝知此事要躬行”,这正是阅读本书的正确做法。虚拟编程道场,等你来闯! 张逸 Lead Consultant,ThoughtWorks 1 bjdp.org北京设计模式学习组(Beijing Design Patterns Study Group) 是笔者在2013年4月6日创办的公益编程操练社区,参见网站http:/www.bjdp.org。 前言 程序员好比运动员,要想在竞技场上获
6、胜,需要在训练场里长期刻苦地练习技艺。 程序员好比士兵,要想在短兵相接的白刃战中取胜,需要在练兵场上长期刻苦地练习格斗。 程序员好比调酒师,要想用炫目的技艺为客人花式调酒1,需要在业余时间长期练习抛瓶。 运动员与和平年代的士兵有大量的时间用于训练。但绝大多数程序员所在的软件公司,在一个接着一个的项目进度的压力下,无法提供大量的时间来供程序员练习,而很多程序员又不愿意在下班后再 碰代码。如此一来,程序员们就成了一直在竞技场上比赛的运动员,一直在敌人面前搏斗的士兵,和一直在客人面前拋瓶的调酒师,他们没有时间练习。 这样不做练习的程序员,只能把在练习过程中所犯的错误都留在了公司的代码库里,成为了烂代
7、码。已有的烂代码延长了给软件添加新功能和修复bug的时间,带来更大的进度压力,这就导致利用工 作时间练习的机会更少了,进而在代码库里留下更多的练习时所犯的错误,形成了更多的烂代码。如此往复,万劫不复。 如此说来,程序员应该像调酒师那样,上班时间努力工作,下班时间操练手艺。 编程是一门手艺。手艺是自己的,如果在公司领导的支持下能在上班时练习固然很好,但若条件不具备,那么就在下班时自己练。其实这也不吃亏,艺多不压身。 本书就是为程序员练习编程这门手艺而撰写的。 这是一本什么样的书? 这是一本讨论如何用TDD(测试驱动开发)方法驯服烂代码的书。无论程序员水平是高是低,都可能写出烂代码。所以驯服烂代码
8、是每一位程序员都会面临的工作。而如何驯服则需要亲手重构代码并 加以体会才能得心应手。本书就是笔者在最近这一年半的时间里,在自己所创办的公益编程操练社区bjdp.org进行编程操练获得的体会的结晶。 这是一本描写编程过程的书。“授人以鱼,不如授之以渔。”这里,“鱼”是结果,而“渔”是过程。如此说来,过程要比结果重要。同样,获得一段重构好的整洁的代码固然很好,但是不如掌握从 最初的烂代码转变到最终的整洁代码的整个过程的重构方法。 这是一本以结对编程的对话形式来展示编程过程的书。自古以来,作为一心学艺的弟子,无不渴望师父能一对一地向自己传授绝技。就好比西游记中的猴王,拜到菩提祖师门下为徒,直到7年之
9、 后,才有缘深夜得到师父一对一的传授,最终获得真传。而与此类似,结对编程就是两人之间一对一进行知识传递的过程,机会难得,每时每刻都弥足珍贵。 这本书能带来什么价值? 本书最大的价值,就是能让人在动手驯服烂代码的过程中真正体会到为什么TDD方法能让开发速度加快。具体来说理由有如下3个。 1)专注。即在开发中只专注于编写恰好能让描述产品特性的测试代码运行通过的生产代码,而不再多写除此之外的其他代码。用TDD的测试先行进行开发,就和男人逛超市一样,他们会按照纸片上的 购买清单(好比照着测试代码)拿货、掏钱、走人,精益适用,不做无用功。而用不用TDD的测试后行进行开发,就好比女人逛超市,看到有什么打折
10、的、新款的、促销的好东西都想买(好比程序员编写 了很多当下用不到的生产代码),从而造成浪费。 2)复用。在TDD开发中编写的自动化测试代码,将来可以复用,能节省以后debug和看log的时间;不写测试而依赖手工debug或看log的做法,将来无法复用,每次都会做很多诸如设置断点、单步 运行、检查变量、打开并阅读日志文件等重复性工作,从而浪费大量时间。 3)反馈早。如果程序员能够频繁运行TDD中的测试,那么就能使软件的绝大多数bug在流入下游测试工程师之前被快速发现和修复。这种反馈会远远早于那种软件只由测试工程师来测试的情况,从而 能节省下面这些人员可观的工作时间:测试工程师发现、描述、报告和跟
11、踪bug;项目经理在各种会议中检查、梳理和分派这些bug;程序员放下手中工作来阅读测试工程师报告的bug并加以重现和修复。 这些人员就能利用所节省的时间来干更有价值的事情,以加快项目进度。 我适合读这本书吗? 本书适合愿意动手尝试用测试先行的TDD开发方法进行编程操练以提高编程技艺的任何人,包括专业的程序员、自动化测试工程师、架构师、开发经理及任何TDD开发方法的学习者,只要您具备下面 的一些经验: 能够编写、编译并运行一段简单的Java程序; 了解或能查询到面向对象的三个基本特征的概念封装、继承和多态; 了解或能查询到有关设计模式和重构的信息。 这本书讲了什么内容? 本书可分为四大部分。 第
12、一部分(第110章)阐释了烂代码的概念。其中第14章用测试后行的开发方法完成了一个编程题目,第58章用测试先行的开发方法完成了上面同样的编程题目。在第9章对比了测试后行与测试 先行的开发方法后,引出了第10章有关何谓烂代码的讨论,从而令人能够看出上面两种开发方法中究竟哪一种更不容易写出烂代码。 第二部分(第1115章)详述了驯服一段烂代码的过程。其中第11章阅读了一段烂代码,并把阅读中所闻到的代码腐臭味用TODO记录下来。第12章编写了3个“用户意图测试”来固化代码现有的行 为,并将这些测试运行通过,为下一步重构做好准备。第13章和第14章分别用釜底抽薪和抛砖引玉的手法来将一个大类分解为若干个
13、小类,即进行重构。第15章继续重构来清除分解大类工作完成后所遗留 下来的代码腐臭。 第三部分(第1618章)详述了编写真正的单元测试的过程。其中第16章用提取接口的办法编写Stub来进行单元测试;第17章用子类化并覆写方法的办法编写Mock来进行单元测试;第18章将被测类 与文件系统之间的这种不适合用于单元测试的耦合,转化为被测类与字符串之间这种适合用于单元测试的耦合,从而通过编程操练体会什么是真正的单元测试。 第四部分(第1920章)总结了驯服烂代码的步骤及方法。其中第19章提出了本书有关TDD开发方法的一种实现IePpTr方法,该方法提出了全面重构的概念,对传统的重构概念进行了扩展。第20
14、 章讨论了如何才能使前面所讨论的良好的编程方法形成习惯并固化下来。最后附录A介绍了有关编程操练的内容,附录B至附录D分别说明了如何在Windows、OS X和Linux上搭建编程操练环境。 1 调酒一般分为英式和花式(美式)两种风格。前者是很正统的调酒方式,没有任何花哨的成分在里面。而后者类似于杂技一样,以炫目的动作去吸引人的眼光。参见:http:/ url=wodhMvyJas K8t0j1LrQfNuJ4IX37R68EVDUWFGdmwRW14zXMbLAN4wxckNOCqCqlKRpUrV0sow9SrynDjbQ8Va。 致谢 本书是多人智慧与努力的结晶。下面如有遗漏,在此表示真心
15、的歉意,并表达我衷心的感谢。 感谢加入公益编程操练社区“bjdp.org北京设计模式学习组”的QQ群(235913915)和微信公众号(bjdp_org)及最近一年半以来参加编程道场活动的每一位匠友,你们的大力支持是本书诞生的动 力。 感谢Kent Beck,我从这位大师的著作Test-Driven Development by Example一书中获得了极大的启发,从而确立了本书编程操练的表达方式。感谢Martin Fowler,这位大师的著作 Refactoring是我参考最多的有关重构的书籍之一。感谢Michael C.Feathers,这位大师的著作Working Effectivel
16、y with Legacy Code为我指出了驯服烂代码时必备的解耦合技术。感谢Robert C.Martin,这位大师的Agile Principles Patterns and Practices in C#和Clean Code两部著作让我在理解面向对象的设计原则和整洁代码方面受益良多。感谢Joshua Kerievsky,正是这位大师的 著作Refactoring to Patterns让我萌生了创办公益编程操练社区“bjdp.org北京设计模式学习组”的念头,并在最近的一年半时间里我所主持的18次编程道场的活动中,逐渐孕育了本书。感谢Gerard Meszaros,这位大师的著作xU
17、nit Test Patterns定义了所有主要的测试相关的词汇,另外我在2014年“TiD AgileChina”大会上在作为大师的中文支持时,从大师那里学到了很多有关编写测试的经 验。 感谢ThoughtWorks公司的领队咨询师张逸能够拨冗为本书作序,这位在敏捷转型、过程改进、企业系统架构、领域驱动设计、大数据、代码质量提升和测试驱动开发方面均有造诣的高手,一直是我 学习的楷模。 感谢Emily Bache和Luca Minudel。我从这两位编程操练高手的书籍和GitHub代码库里获得了本书所用的几个编程操练题目和参考解决方案。操练这些题目真的让我获益匪浅。 感谢下面的朋友为本书撰写提
18、供的宝贵反馈意见:许晓斌,王立杰,陈臣,王洪亮,仝键,罗万华,申健,Steven Mak,栾大成,徐宪武,韩杰,李志博,杨武兵,wuqiang,zhangzh,董英,谢 钊,林进峰。 感谢下面为bjdp.org公益编程道场免费提供场地的公司与个人:图灵公司谢工、袁野,华夏煤安祁智军,爱帮网郝俊,UnitedStack程辉,龙泉寺信息中心朱雪花、李子 豪,CSDN蒋麒霖,博彦科技廖君仪,首信公司范云飞,直真科技饶林,优纳科技刘明星,天正华光廉雨,互动出版网李开伟,联想北京研究院喻泽高,京东商城北 京总部蔡德辉、宋宁。 感谢Odd-e公司的姚若舟与张博超邀请我观摩他们主持的精彩的TDD软件开发公开
19、课,这个课程及姚若舟所给予我有关驯服烂代码的反馈,促使我修订了本书对烂代码的定义。 感谢编辑杨福川和孙海亮,没有他们的反馈意见与鞭策督促,本书不会这样快问世。 感谢我的夫人薛静,她为我辞职撰写本书提供了最主要的经济支持。感谢我8岁的儿子乐乐,他很懂事地自己在一旁玩,从而让我腾出时间能尽快把书写完。感谢岳母、妹妹、妹夫、堂妹和堂妹夫帮我 分担各种家务事,这为我尽早完成本书赢得了宝贵的时间。最后感谢我的父母,每当我带着乐乐去探望他们时,他们总是默默地为我承担一切家务。当我每次吃完他们为我备好的饭菜后,他们总是 说:“快去写书吧,碗筷我们洗。” 第1章 刻舟求剑的文档 “什么是软件?”20世纪90年
20、代初的一个冬日,在北京东南部的一所大学里,一位年近花甲的老师,给我们这些计算机系的学生讲软件工程这门课时,问了这个问题。对于当时几乎没有机会接触计算 机的我来说,软件就是学校计算机房里那些DEC小型机上令人费解的命令,和286个人计算机里那些好玩的“吃豆子”和“赛车”游戏。“软件不仅仅是程序,还包括描述程序的文档。软件就是程序加文 档。”老师对软件的定义,深深地刻在我的脑子里,其程度之深,以至于在之后的很长一段时间里,总令我觉得文档对于软件的影响力,似乎要超过程序。 这一点在我大学毕业后20年的软件开发相关工作的实践中,不断地得到印证。各种各样的文档需求文档、概要设计文档、详细设计文档、测试文
21、档等,在我先后经历的多个软件开发项目中,始终 占据着重要的地位。“毕竟,只要文档在,就不怕开发人员的频繁更换。”一位软件开发经理这样对我说。除了要写Word或Excel的文档,程序员们还被要求在源代码中写尽量详尽的注释。在软件开发经 理眼中,撰写文档和编写注释的能力,是衡量程序员是否称职的一项重要标准。 “为保证客观性,软件开发完成后,应该由不同的人员来对其进行测试。”老师的这句话也时时萦绕在我的耳边。这句话的影响力是如此巨大,以至于前些年我做程序员时,我和周围的程序员们都一 致认为测试就是测试工程师的事情。在10多年中,我经历的每一个项目,都无一例外地有一个独立于开发团队的测试团队,开发团队
22、将代码开发完成后,简单地在自己机器上运行一下,然后就将代码提交 给测试团队去测试了。 十几年来,不管是开发新功能还是修复bug,我一直在努力地撰写文档,编写和修改代码及注释,然后交给测试人员去测试,再去修改测试人员提出的bug,这一切看起来都像教科书上描述的那样地 完美和正确。但是最后我却难过地发现,用这种方法开发出来的软件,无一例外逐渐沦为烂代码。在烂代码的沼泽里,即使有文档,也读不懂代码;即使bug很小,也不敢修改代码。我甚至怀疑,这种方 法或许会助长烂代码的滋生。这些文档就好像“刻舟求剑”故事中那个刻在船身上的记号。让我们先用这种传统的测试后行1(test last)的开发方法,做一个编
23、程操练2吧,来看看其中会有什么问题。 对于本书中所有的编程操练,我都将邀请您我的亲爱的读者来与我一起结对编程。 “啊?和我结对编程?我还从来没试过哩!”读者可能会说3。 结对编程其实一点都不神秘,如果把编程比作打网络游戏,结对编程就好比两个人结伴去打魔兽,除了可以相互学习切磋之外,还能相互有个照应。一起来看看本书的第一个编程操练。 这个操练是我于2013年9月为在“北京设计模式学习组”的第9次活动中操练Observer设计模式而编写的。灵感来自于我在酒店下榻时,在大堂里看到的墙壁上悬挂的那些显示世界上各个主要城市的时 间的时钟。我在想,如果所有这些时钟都走时不准,酒店大堂服务员一个个地分别调时
24、间太麻烦,而这位服务员的智能手机上肯定用的是该酒店所在地的当地时间,要是能够在调准服务员手机时间的同 时,将酒店大堂墙壁上所有城市的时钟根据时差相应地自动调准,那该多方便。 假如在北京一家酒店的大堂里有5个时钟,分别显示北京、伦敦、莫斯科、悉尼和纽约的时间。其中,伦敦与UTC(Coordinated Universal Time,协调世界时)时间4一致,北京比UTC时间早8小 时,莫斯科比UTC时间早4小时,悉尼比UTC时间早10小时,纽约比UTC时间晚5小时5。若所有这些城市的时钟都多少有些走时不准,需要调整时间时,大堂服务员只需调准自己手机上的北京时间,那么 墙壁上那5个城市的时间就能相应
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 驯服 代码 编程 操练 悟道 html
链接地址:https://www.31doc.com/p-5518773.html