为何我喜爱读他人的代码,而你也应该去喜爱它
原作者 : Alan Skorkin
翻 译:Xguru
这让我想到很多程序员讨厌去阅读代码,来接受它吧。人人都喜欢编写代码--写代码是很有乐趣的事。但阅读代码却是一种困难的工作。它不仅仅繁重,而且很无聊,让我们面对这个事实,任何不是自己写的代码都是差劲的(嘿嘿,虽然我们没有这样说过,但是其实我们都是这样想
的)。甚至当你写完代码后的仅仅几个小时之后,你的那些代码就开始变得越来越烂了,时间一长,你就会把它当作看起来的那种差劲作品。
所以,你又何必要去花费时间来审视别人蹩脚的代码呢,这段时间你完全可以用来
自己去写一些非常优秀的代码,为什么不这样尝试一下,把自己写好的代码放上几个小时再回头看看,它是否依旧非常优秀呢?如果你不站在前辈们的肩膀上,你将没有可能成一个为技艺精湛的大师。其中一种途径就是亲自找到一个大师,让他把他所有的知识全部传授给你--当然这是有可能的,虽然可能性不高,你必须非常走运才能获到这种机会。然而你可以不用想着去碰运气, 我们很幸运的处在这样的一个职业里--大师们的经验和知识都在那里等着我们去吸收,这些都蕴涵在他们所写 的代码里。你所要做的事就是去阅读它,当然它可能会比找一个人坐在你旁边向你解释这些多占用一点时间,但是这是实现起来可能性较高,透视全局地思考下,若想成为优秀的木匠,你就必需观察大量的拥有优良结构的家具。
我喜爱阅读代码,我的直觉告诉我,你也将会从中受益匪浅,是的,它的确可能是无聊、令人恼火的的事,
但是它所产生回报非常值得你去努力。考虑这个,如果你想成为一个优秀的代码写手,你是否专门将注意力集中在编写代码上?你可能尝试过,但是你无法单单靠写代码走得更远。这是个普遍公认的事实,大多数卓越的写手都是如饥似渴的阅读者。在你希望去写些体面点的东西之前,你需要阅读其他卓越的写手的作品,吸收不
同的风格,看看在你之前别人有了怎么样的尝试。从而培养你自己的创造性。你的知识会慢慢增长,最后你自己写的东西会显得成熟,你将慢慢找到编码的"感觉",编写代码也是同样如此,如果你从来没有阅读过其他卓越的代码,
你又凭什么指望能写出一些优雅的代码?答案就是别指望这码事了。对于优秀的程序员来说,阅读卓越的代码就像作家需要阅读卓越的书籍一样重要。
尽管所有的这些都不容易让人信服,但是有一个事实是毋庸置疑的--作为一个专业的开发者,擅长阅读代码能够对你的生存十分重要。如今任何正式的项目都是一个团队的 努力,所以这将有大量的代码不是你所提交,但是你又不得不要与其工作、修改和扩展它
。因此,阅读代码可能将是你所拥有的最常用到并且最有用的技能;你最好尽快咬紧牙关去掌握它。
我无法告诉你我见过多少次这样的情形:程序员在陌生的代码里上下滚动屏幕,几分钟以后,脸上就出现了郁闷的表情。然后他们就宣布这代码就是不具备可读性的废物,为何要在这上面浪费时间呢;我们只能用其他的某种方法去解决这个问题。我不确定他们期待什么,是靠潜移默化就能理解代码的意义?或者是就靠聚精会神地盯着这些代码,就期待能获得启迪?你不应该只长时间的注视着代码,你需要理解它并将其为己所用。这里有一些我喜欢使用的技巧,它并不是一个详尽的清单,但是我发现这些方法特别有用。
1. 试着去编译和运行它。这通常是一个简单的处理步骤,比如当你寻找工作性的代码(与随意的编码相反)。然而这也并非总是如此,你能通过将其构建和执 行的过程中学习到代码里很多高层的结构组织。在工作代码的主题中,你是否熟悉如何构建你当前的项目?项目的构建通常是复杂的,但是能够通过一点点地了解构建过程可执行码是如何产生的,可以让你获得很多的体会。
2. 不要只着眼于细枝末节。第一件事你需要做的,就是在你所读的代码结构和风格中找点感觉,开始浏览和试着弄明白各个代码段想要做些什么。这会让你熟悉整个代码库的高层的结构,同时也给你正在处理的代码(无论是良好分解的、或者是意大利面条式【译注:形容代码混乱难以梳理】的等等)一些构思,这是你找到问题切入点的时候(任何发生的事,主函数、小型服务程序、 控制器等),观察代码是如何从这里分支出去的。但是不要花费大量的时间在这个上面,随着你对代码有更深入的了解,你可以随时返回到这个步骤。
3. 确认你了解了它所有的结构。除非碰巧你是在编程语言上的首席专家,否则这里可能有些它让你不了解的行为。当你从较高层级的俯览过其代码时,记录下你不可能不熟悉的结构。如果记录的东西非常多的话,你的下一步就很明显了。如果你对逐句的代码是如何工作不怎么了解的话,就不要走得太远。尽管只有几个结构你不太熟悉,如果你去仔细探究它们的话,可能会为你带来良好的构思。你现在也是正在探索以前你所使用的编程语言中一些不了解的东西,我很乐意为此花费几个小时去阅读代码。
4. 现在你获取到了大多数结构的优良构思,是该任意来几个的深入实践的时候了。像步骤2一样,开始在代码里漫游,但是这次,从中挑选出任意几个函数或者类,开始一行一行地进行分析。这是艰苦工作的开始,但是同时也是
你获得主要成果的开始。这里的构思就形成了你所看的这个代码库的观念模式。也不要在这上面花费太多的时间,但是在继续前进之前,试着深刻地吸收一些内容丰富的模块。这是你能够在了解更多背景下反复地返回、并每次都能从中得到更多的东西的另外一个步骤。
5. 毋庸置疑的事就是你在前几个步骤中对某些方面会产生疑惑,所以,这是你最佳的时间去运行和阅读一些测试了。当你在测试中增加对代码的了解的同时,将有或多或少潜在的麻烦在潜伏着你。我经常会感到惊讶,当阅读和了解代码时,开发者竟然会忽略其中写得很好很全面的一个测试套件。但是有时候,它没有提供测试用例。
6. 你说它没有测试用例么,听起来像是该写些东西的最好时机了。这是很有益的事, 这会有助于你自己的理解,改善代码库、阅读的时候同时写些代码,这是给你自己找点事干最好的机会。即使它已经提供有测试案例了,但是你总是能写出让你更受益的东西。测试代码经常需要换个不同的角度去思考,在你将其弄清楚之前,有些概念会躲避着你。
7. 抽取少量稀奇有趣的代码,将其写成独立的程序。我发现这是在阅读代码过程中有趣的练习,即使改变了你的计划进度。尽管你不了解代码底层的细节,但是你可能会对代码在高层的行为有了一些思路。为什么不抽取一些特
殊的函数将其转变成一个独立的程序呢?当你让一小块代码独 立地执行时,将更易于调试,而且这又允许你有了额外的步骤去获, 去你正在研究的代码有了得更多见解。
8. 这代码是肮脏和有坏味的吗?那么为何不将其重构呢。我不是建议你重写整个代码库, 但是即使对一小部分的代码进行重构也能使你的理解上一个层次。开始将你所理解函数改成独立的函数。在你了解之前,原有的规模巨大的函数看起来容易做到的,
你能在大脑里修改它。重构允许你将代码变成你自己东西,而无需将其完全重写。它能为你提 供优秀的测试用例,但是即使你没有这个,仅仅是测试并且只是讲你确认了的函数提取出来。虽然这个测试看起来完全是不足够的 --作为一个开发者,学着相信你自己的技术。有时候你只好需要这样去做。
9. 如果看起来很无助的话,那就为自己找个同伴一起阅读代码。你可能不是能在读这份代码里受益唯一的人,所以去寻找一个其他的人并试着一起阅读。然而不要去找那些专家,他们会在高的层次向你解释这一切,你会错过当你拾起代码自己去经历时所能得到其中所有微妙的地方。如果不见效的话,你就不要再去强求,有时候最好的办法就是你去提问,问你的同僚。或者你是在读开源代码的话,试着去在互联网上寻求他人的帮助。但是请记住,这是最后一步,不是第一步。
如果时间所迫,你需要适当地加快速度去了解一些代码时,只能选上面的一个步骤的话,我会选择重构
(第8步)。你不能很快地将其了解清楚,但是如果你做了这个工作的话,你将会牢牢地掌握它。没关系,你需要将这句话记在心里:如果你是刚接触一个重要的代码库,
你不可能立刻弄懂它们,甚至不能快速地弄懂它们。这将耗费数天、数周或者数月的不懈的努力--只要去接受它就行了。如果有专家加盟的话你也不能显著的减少时间 (这是我下个教学系列的文章 将讨论的)。然而无论如何,如果你在读代码(还有写代码)是有耐心的、有条不紊的,你最后总能变得通晓项目所有的方面,并且当涉及到代码库的时候,你会成为能够胜任他人难以企及工作的人(go-to man)。或者你会选择成为逃避阅读代码、总是找人向你解释问题的家伙。我知道我会选择哪一个的。
寻找代码阅读机会--而不要去逃避它们
我们喜欢编写新的代码,一个诱人原因就是我们能用它恰到好处地处理问题。好吧,可能这次不是,但是下次一定就是了。事实上,你一直在改进你的技艺,但你永远不可能恰到好处的处理问题。这就是写新代码一直存在的价值的原因,你能够获得锻炼并且磨砺你的技巧,其实阅读和把玩别人所写代码也有同样的(如果没有更多的话)价值。你不仅仅能从中得到一些有价值的技术知识,还同样经常能获得一些领域知识(归根结底,代码是文档的最终的形式),这仍然是很有价值的东西。
即使代码使用奇怪的方式所编写,不经过转换加密的话,都可能是有价值的。你懂我所说的那类代码,它看起来是加密混淆过了的,但是它并不是有意而为之的(由于某种原因,Perl经常就是这种代码☺),无论何时我见到这样的代码,我就会想到了这个方法。把这东西想象成是只能经过解密破译后你才能从中有所学的东西。是的,这是很痛苦的事,但是请你容许它,有时候你也会因为某种神秘琐碎的原因,写出这种看起来像被混淆了的代码(不要否认它,你知道这是真的)。好了,如果你如此这般的投入了时间去阅读代码,你更可能最后能够写出这种代码--并不是意味着你一定要将其写出、而是你将拥有写出它的能力。最后说一句,态度决定一切,如果你把阅读代码视作乏味无聊的事,它就会变得乏味无聊,你就会去逃避它,但是如果你选择将其看作一次机遇的话--那么好事就要降临了。
by XGuru
is licensed under a Creative
Commons 署
名-非商业性使用-相同方式共享 2.5 中国大陆
License. 原文请
看这里。
Thanks to bearice for debugging.