浪漫主义计算机科学家的真知灼见——《代码整洁之道》
熟悉我的人都知道我每次写文章都要敬从当涂太白墓请来的李白三杯酒,很多人问我为什么写文章之前不拜韩愈或者苏轼反而拜成就在诗不在文的李白呢?我每次都要解释:李白是捞月的诗人,Monkey是捞月的动物,李白是我们这些Code Monkey的祖师爷。
谁说李白不会写文的?他不是写过《吓蛮书》吗?
谁说李白不会写Java语言的?你怎么知道《吓蛮书》上那些唐玄宗和满朝文武都看不懂的蝌蚪文字不是Java语言?
Code Monkey这个称呼来源于世界级软件开发大师,设计模式和敏捷开发先驱Uncle Bob在2007年唱过的《Code Monkey》,尽管Uncle Bob不是诗人,但是文笔同样幽默风趣,是我心目中李白式的浪漫主义计算机科学家。
Bob大叔的巨著《代码整洁之道》是很有趣又非常实用的一本书。代码质量与其整洁度成正比是众所周知的事实,如何打磨这些代码让它们变得整洁才是Bob大叔这本书所要传授的。
本书的画师Kohnke也是王维转世,他不但用每一章第一幅插图(以下简称“主题图”)概括了整章的内容,还在每幅主题图中加入了“KOHNKE”的暗记,边读书变找暗记也是件有趣的事。
第1章 《整洁代码》
本章的主题图是一位古代的程序员正在用雅典娜神庙的圣水满头大汗地clean写满code的纸(本章标题英文原版为“Clean Code”,“clean”有“清洗”的意思)。
很多团队在项目初期进度突飞猛进,半年以后却举步维艰,对代码的每次修改都要影响其他两三次代码。这团乱麻越缠越大,最终积重难返。本章指出了解决以上问题的根本办法:让代码比你接手前更干净。
第2章 《有意义的命名》
本章的主题图是一对夫妻拿着一本《Baby Name(宝宝取名大全)》在给他们的子女(包括妻子肚子里的)取名。
编程时对文件、常量、变量、函数的命名比给宝宝命名更复杂:毕竟给宝宝命名可以参考《宝宝取名大全》,而“买一本《宝宝取名大全》,你就不愁命名了”的梗出自《如何写出无法维护的代码》;其次给代码命名需要考虑变量、常量、方法乃至不同数据类型、对象类型的区别,而给宝宝命名只需要不和长辈重名即可。
Bob大叔感觉给代码命名比给宝宝命名的难度比国内读者更甚,因为中国人自带给宝宝命名的时候考虑辈分的光环,例如合肥聂家的“士尔绍先志,传家义理长”,在此向民族英雄聂士成致敬。
第3章 《函数》
本章的主题图是一只6只手和6只脚(成语“七手八脚”的外国版?)的半人半虫的怪物嘴里念念有词:“public void callAction{…”。
函数作为语言的动词,应当每个函数都完成一个功能并且这个功能仅有该函数完成,同时要尽可能短小。
Bob大叔认为大师级的程序员把系统当做故事来讲,而不是当程序来写——构建更为丰富且更具表达力的动词用来讲故事。这位浪漫主义计算机科学家如果生在没有电脑的时代,说不定就是李白一样的大文豪了。
第4章 《注释》
本章的主题图是一群长舌妇七嘴八舌说些什么,她们说的内容疑似为《窦娥冤》选段“有一等妇女每相随,并不说家克计,则打听些闲是非”。
Bob大叔认为注释的恰当用法是弥补我们在用代码表达意图时遭遇的失败。与其给糟糕的代码写注释,不如重构那堆糟糕的代码。
第5章 《格式》
本章的主题图是三个本该匪匪翼翼、持枪鹄立的水兵东倒西歪、烂醉如泥的丑态。缩进整齐的格式的重要性不亚于步调一致的军容对部队的重要性。
对于近年入行的程序员来说,格式问题很难遭遇到,这是因为本书出版后各大IDE都遵循了本章中Bob大叔的示例来自动修改代码格式。
第6章 《对象和数据结构》
本章的主题图是本书画师Kohnke的自画像,对象和数据结构都太抽象,不太好画,用自画像能沾private的边。
本章在面向对象时代给面向过程代码翻了一案:面向过程代码便于在不改动既有数据结构的前提下添加新函数,面向对象代码便于在不改动既有函数的前提下添加新类;反过来说就是面向过程代码难以添加新数据结构,因为必须修改所有函数,而面向对象代码难以添加新函数,因为必须修改所有类。在任何一个复杂的系统都会同时存在数据结构和对象,我们需要判断的是我们需要的是需要添加的新的数据类型还是新的行为函数。
第7章 《错误处理》
本章的主题图是一对没买保险的夫妇面对惨烈的车祸惊慌失措、狼狈不堪。
软件Crash就像车祸一样猝不及防,然而你的软件里可没有保险公司和交通事故快速处理中心,所以程序员必须要防患于未然。
本章中Bob大叔总结了一套在编写代码时处理可能发生的Crash的技巧和思路。与其他人的思路不同的是,他的异常处理独立于业务逻辑之外,能保证代码既稳定又整洁。
第8章 《边界》
本章的主题图是母亲洗澡忘记锁门时儿子不小心闯入了浴室,说是流氓硬闯女浴室的请翻上去看第2章主题图。
我们很少控制软件中的全部代码。有时我们购买第三方SDK(其实闭源SDK也是免费居多)或者使用开源代码,有时我们依赖其他团队打造的moudle或library。我们都要将保持外来代码的边界整洁,避免破坏整个软件的构造。使用代理模式就是保持边界整洁的最好办法之一。
控制边界整洁的另一个好处就是可以使用尚不存在的代码,给敏捷开发模式带来了可行性。
第9章 《单元测试》
本章的主题图是Bob大叔用于一个C++软件的单元测试(当年Java发明伊始,还没入Bob大叔的法眼)时的歌词配上Bob大叔年轻时爱听的四重唱乐队的图,Bob大叔用主题图向自己的偶像歌手致敬,他自己也因为总结出了TDD三定律成了别人的偶像。
本章告诉我们要把单元测试的代码当作软件的一部分,与生产代码一视同仁,保证它们可扩展、可维护、可复用。
第10章 《类》
本章的主题图是大学课堂上,老师在教诲形形色 色的学生(“class”不仅有“类”的意思,也有“课堂”的意思)。类和大学课堂有个共同点在于类是由不同的代码块(常量、变量、函数)组成的,大学课堂是有不同背景的学生(地域、民族差异)组成的。
本书在此之前一直在讨论代码语句及由代码语句构成的函数的表达力,但除非我们将注意力放到代码组织的更高层面,就始终不能得到整洁的代码。
第11章《系统》
本章的主题图是《The Bottle City of Kandor》,一部国内冷门的DC动漫。
管理一个城市是一个人无法做到的,一个城市的运转需要不同的部门负责水电、交通、司法等。一个软件中也要演化出恰当的抽象等级和模块,负责细节和具体实现的组件在不干预全局的情况下也能正常运转,目前最流行的MVP架构就把代码分为了M、V、P三层。
第12章 《迭进》
本章的主题图是一只蝴蝶,蝴蝶的发育过程属于经历几次发育周期后完全没有毛毛虫影子的完全变态发育。
Bob大叔在本章中总结了自己数十年间通过迭代设计达到整洁代码目的的经验,用把毛毛虫代码迭进成蝴蝶代码经验把毛毛虫程序员指导成蝴蝶程序员。
第13章 《并发编程》
本章主题图是一只双头马,可以理解为两个并发的Thread。
并发是一种解耦策略。他帮助我们把做什么(目的)接何时做(时机)分解开。本章讨论了并发编程的必要性和编写整洁的并发代码的建议。
Handler和ThreadPool的工作原理是我做面试官的必问内容,对并发编程的了解可以看出一个Android工程师的工作经验是不是都是UI层次的表面文章。
第14章《逐步改进》
本章的主题图是一个清正廉明的法官面对“公说公有理,婆说婆有理”时一脸无奈的表情。
“清官难断家务事”的根本原因在于在约法三章的年代法律只规定了“杀人者死,伤人及盗抵罪”,断家长里短案没有法律依据。软件开发的过程也是一个循序渐进、不断完善的过程,一蹴而就是不可能的。一个软件应该像法律一样日益完善,走一个逐步改进的过程。本章中Bob大叔分享了一个规模扩大后出问题的模块的逐步改进案例,用巨大的篇幅告诉读者一个模块是如何整洁起来的。
第15章《JUnit内幕》
本章的主题图是一位考古学家在探索雕刻着“JU”的古代石碑。
JUnit是最古老的Java语言的单元测试框架,使用JUnit的好处在于它能完成结果正确与否的判断,我们只需要看看它告诉我们结果是否正确就可以了,在一般情况下会大大提高效率。Bob大叔显然不满足于短期的结果,他在本章深入剖析了JUnit的原理。
第16章《重构SerialDate》
本章的主题图是一个小男孩不想吃枣核,Bob大叔又玩了一个双关梗——“Date”既有“日期”的意思又有“枣”的意思。
写Java的程序员都知道Date是多么坑爹的类,SerialDate是Date的非官方改进,而Bob大叔再此基础上做了进一步改进。因为年代久远,具体代码参考意义不大,读本章要读精益求精的精神。
我再告诉大家图中的一个彩蛋:就像加上“Serial”就让“Date”变成“SerialDate”一样,只要加上一个“and”就能味同嚼蜡、难以下咽把的“Date Nuts”变成Bob大叔年轻时爱看的喜剧短片《Dates and Nuts》。
第17章《味道与启发》
本章的主题图是一辆推土机正在治理臭气熏天的垃圾山。
本章的主要内容是Bob大叔藉由遍览和重构几个程序后总结出的一份清单,读过这份清单后多么容易闻出代码里的令人不舒服的味道,我想讲一个真实的故事:InMobi进军中国时,我一边看着官方demo里用JSONObject的getString方法解析JSON的代码一边问技术支持:“这是什么代码?印度人写的吧?”他答道:“是的,这就是印度人写的。你怎么知道是印度人写的?”
本文转载自异步社区
原文链接:https://www.epubit.com/articleDetails?id=NC7E3EF944650000160335BB010E0BB70
- 点赞
- 收藏
- 关注作者
评论(0)