4.如何阅读项目源码?
每一个程序员都有阅读项目源码的经历,很多初学者在第一次阅读项目源码时都会产生一个疑问,面对规模庞大的项目源码,到底应该从何处下手?本节要回答的便是如何阅读源码这个问题。
明确目的
在开始之前,我们应该首先明确自己阅读项目源码的目的。有些程序员是需要维护这个项目,例如修正项目中的bug,或是为项目扩展新的功能;有些程序员是需要对这个项目加以利用,避免重复造轮子;有些程序员是为了提高自己的代码质量,而去阅读优秀项目的源码。首先要说明的是,尽管我们将优秀的代码比作文章,但代码毕竟不是小说一样的读物,如果是为了读代码而去读代码,在一个庞大的项目面前,相信很难有人能够坚持下来。因此我们必须要明确自己阅读源码的目的,这样才能有针对性地解决问题,同时,明确的需求也是我们阅读源码的动力来源。
阅读方法
阅读源码遵循的一个原则是自顶向下,首先树立对项目的整体认识,然后进入项目的模块乃至函数层面的细节部分。因此,如果拥有项目相关的资料与文档,例如概要设计文档、详细设计文档、测试文档等,阅读源码就可以事半功倍。如果没有项目文档,我们可以首先查看项目的架构,项目中文件夹的划分往往表示模块划分,通过对目录结构的梳理我们也能对项目形成初步认识。另外,当前层级目录中的readme文件也是重要的说明文件。
在阅读了项目相关的资料与文档之后,我们对项目整体有了初步的认识,下面就要开始源码的阅读了。从哪里开始阅读呢?首先需要明确我们关心的模块,找到项目中相关的功能模块,从该模块开始阅读,而不是阅读与所需功能无关的模块。在锁定了模块之后,就要开始寻找程序入口的地方,例如对于C++和Java,入口函数是main函数,找到了程序开始的地方,我们就能顺着程序的主线梳理核心的代码逻辑了。
阅读源代码应该遵循先整体后部分的原则,而不是一头扎入细节,即阅读的方法应类似于广度优先遍历,而不提倡深度优先遍历。程序的主体是层次最高的代码,往往比较简单,调用的函数往往也较少,根据所调用的函数名以及层次关系一般可以确定每一个函数的大致用途。在理解了程序主体的核心逻辑之后,可以依次阅读程序主体调用的层级较低的模块和函数,分层阅读时,需要注意区分系统函数和开发人员编写的函数,注重阅读开发人员编写的函数。在阅读代码的过程中,不能指望阅读一遍即能掌握,反复的阅读可以加深对于代码逻辑的理解。如果程序的逻辑较为复杂,还可以考虑画出函数的调用关系图,变量的变化方式等。
编译运行
想要理解代码,只通过阅读是不够的,最好的方式是运行代码,这就需要我们学会调试,对调试的内容感兴趣的读者可以阅读第5节。在阅读代码时,我们可以在关注的地方设置断点,调试程序运行到断点处,查看此时的调用栈以及各变量值的变化情况。单元测试是理解源码的另一个有效渠道,单元测试中的测试用例能够反映代码作者对于测试用例经过程序执行后的期望结果,读者往往可以通过单元测试加深对源码程序逻辑的理解。
编码之道
最后,每个程序员在阅读项目源码之后都应该学习其中优秀的代码编写之道,例如对于设计模式的应用,良好的编程习惯等。在之后自己编写代码的过程中,严格要求自己的代码质量,因为我们的代码一定会在将来被其他人或者自己反复阅读。刚入门的程序员往往只将功能的实现放在第一位,而忽略了我们会花费很长时间阅读我们自己写过的代码,忽视代码质量只会让一个项目变得越来越臃肿和耦合,想要再维护就会花费大量的精力。为了避免破窗效应,我们应该在编写项目的最开始就严格要求代码质量,并自始至终贯彻这一原则。