记得在开源流行之前,我看过的代码紧限于所参与的项目,能有个几万行就不错哩。后来很多优秀开源项目都相继蹦出来了,阅读的代码量那叫一个大呀!不得不看。我现在掉到android这个大坑里,每天都要看很多源代码。以前做过J2EE,看Struts2、Lucene、OSWorkflow、iText等项目的源码,动机有三:文档不足、找问题的原因、好奇。当时有个项目用到了Dojo,这家伙可以说是源码最多的开源Javascript框架了,文档却严重不足,也没什么人用,只能看源码了。
要想快速并高效地阅读源码,一定要有好方法,不然看着会挺费劲,当然,用什么方法取决于具体的情况。我就把自己总结的方法给大家show一下,互相交流交流:
1、一边阅读代码一边写注释。这是我用过的最好的方法,对代码理解得更深入,看一些重要代码或者特别难懂的代码时挺有用。更何况,注释也是一种文档嘛。
2、一边阅读代码一边绘制UML。这个方法适用于类之间的关系较复杂和调用层次较深的情况,我一般都是先绘制顺序图,然后为顺序图中的类绘制关系图。
3、通过Debug来跟踪程序的主要执行过程,这样就可以分清主次了,阅读的时候更有针对性。
4、类的快速阅读。先弄清楚它在继承链中的位置,看看它的内部状态,也就是成员变量,一般来说,类的对外接口都是对成员变量的访问、加工、代理等,然后看看它的对外接口,也就是公有成员函数,识别核心的一个或多个函数,这时候你应该可以大概了解这个类的职责或作用了。可能这个类是某个设计模式中的一个组成部分,所以,设计模式的掌握对代码的快速阅读也是很有帮助的。
5、带着问题去阅读。比如想了解android中的消息机制,那么看看Looper、Handler、MessegeQueue这几个类就可以了,其他的不要去看,要不然就跑题了。
下面列几个阅读源码时所处的情景,在特定场景下用哪些方法:
不太熟悉业务逻辑,还不是很清楚它是干啥的,可以用3、5。
代码量很大,有几十万行,甚至百万行,可以用2、3、5。
你无法看见程序的运行过程,比如没有用户界面,也有可能是无法运行的,可以用3、5。
设计复杂,用了大量的设计模式,调用链很深,可以用1、2、3、4、5。
时间有限,没有那么多时间让你看源码,可以用3、5。
分层次阅读
在阅读代码的时候不要一头就扎下去,这样往往容易只见树木不见森林,阅读代码比较好的方法有一点象二叉树的广度优先的遍历。在程序主体一般会比较简单,调用的函数会比较少,根据函数的名字以及层次关系一般可以确定每一个函数的大致用途,将你的理解作为注解写在这些函数的边上。当然很难一次就将全部注解都写正确,有时候甚至可能是你猜测的结果,不过没有关系这些注解在阅读过程是不断修正的,直到你全部理解了代码为止。一般来说采用逐层阅读的方法可以是你系统的理解保持在一个正确的方向上。避免一下子扎入到细节的问题上。在分层次阅读的时候要注意一个问题,就是将系统的函数和开发人员编写代码区分开。在c, c++,java ,delphi中都有自己的系统函数,不要去阅读这些系统函数,除非你要学习他们的编程方法,否则只会浪费你的时间。将系统函数表示出来,注明它们的作用即可,区分系统函数和自编函数有几个方法,一个是系统函数的编程风格一般会比较好,而自编的函数的编程风格一般比较会比较差。从变量名、行之间的缩进、注解等方面一般可以分辨出来,另外一个是象ms c6++会在你编程的时候给你生成一大堆文件出来,其中有很多文件是你用不到了,可以根据文件名来区分一下时候是系统函数,最后如果你实在确定不了,那就用开发系统的帮助系统去查一下函数名,对一下参数等来确定即可。
写注解
写注解是在阅读代码中最重要的一个步骤,在我们阅读的源代码一般来说是我们不熟悉的系统,阅读别人的代码一般会有几个问题,1搞明白别人的编程思想不是一件很容易的事情,即使你知道这段程序的思路的时候也是一样。2阅读代码的时候代码量一般会比较大,如果不及时写注解往往会造成读明白了后边忘了前边的现象。3阅读代码的时候难免会出现理解错误,如果没有及时的写注解很难及时的发现这些错误。4不写注解有时候你发生你很难确定一个函数你时候阅读过,它的功能是什么,经常会发生重复阅读、理解的现象。
好了,说一些写注解的基本方法:1猜测的去写,刚开始阅读一个代码的时候,你很难一下子就确定所有的函数的功能,不妨采用采用猜测的方法去写注解,根据函数的名字、位置写一个大致的注解,当然一般会有错误,但你的注解实际是不但调整的,直到最后你理解了全部代码。2按功能去写,别把注解写成语法说明书,千万别看到fopen就写打开文件,看到fread就写读数据,这样的注解一点用处都没有,而应该写在此处开发参数配置文件(****。dat)读出系统初始化参数。。。。。,这样才是有用的注解。3在写注解的使用另外要注意的一个问题是分清楚系统自动生成的代码和用户自己开发的代码,一般来说没有必要写系统自动生成的代码。象delphi的代码,我们往往要自己编写一些自己的代码段,还要对一些系统自动生成的代码段进行修改,这些代码在阅读过程是要写注解的,但有一些没有修改过的自动生成的代码就没有必要写注解了。4在主要代码段要写较为详细的注解。有一些函数或类在程序中起关键的作用,那么要写比较详细的注解。这样对你理解代码有很大的帮助。5对你理解起来比较困难的地方要写详细的注解,在这些地方往往会有一些编程的技巧。不理解这些编程技巧对你以后的理解或移植会有问题。6写中文注解。如果你的英文足够的好,不用看这条了,但很多的人英文实在不怎么样,那就写中文注解吧,我们写注解是为了加快自己的理解速度。中文在大多数的时候比英文更适应中国人。与其写一些谁也看不懂的英文注解还不如不写。
重复阅读
一次就可以将所有的代码都阅读明白的人是没有的。至少我还没有遇到过。反复的去阅读同一段代码有助于得代码的理解。一般来说,在第一次阅读代码的时候你可以跳过很多一时不明白的代码段,只写一些简单的注解,在以后的重复阅读过程用,你对代码的理解会比上一次理解的更深刻,这样你可以修改那些注解错误的地方和上一次没有理解的对方。一般来说,对代码阅读3,4次基本可以理解代码的含义和作用。
运行并修改代码
如果你的代码是可运行的,那么先让它运行起来,用单步跟踪的方法来阅读代码,会提高你的代码速度。代码通过看中间变量了解代码的含义,而且对 以后的修改会提供很大的帮助
用自己的代码代替原有代码,看效果,但在之前要保留源代码
600行的一个函数,阅读起来很困难,编程的人不是一个好的习惯。在阅读这个代码的时候将代码进行修改,变成了14个函数。每一个大约是40-50 行左右。