为什么要阅读源码?
说到读源码,让我想起来了读书,古语有云:“读破万卷书,下笔如有神”。
通过源码的阅读,把一些零碎的知识点整合起来,让我们更好的了解框架的优缺点
多读读大师的想法技巧,可以让我们自己写出结构更优质的代码
可以让我们对自己写的代码有更深层次的认识,利于排查错误、性能调优
阅读源码遇到的问题
很多读者朋友在阅读源码的时候应该都或多或少遇到过这些问题:
"没有经验的技术差底子薄的初级程序员,如何阅读项目源码? "
"有人阅读过 mybatis 的源码吗 ?就看一个初始化过程就看的已经头晕眼花了,小伙伴们支支招吧!!!"
"源码应该怎么阅读,我曾经尝试阅读一些源码,例如alibaba的druid中sqlparser部分,spring-mvc,但是发现很吃力,都说debug是最好的阅读方式,我在debug时经常有跟丢的现象……就是走着走着感觉好像进入了一些我当前不太关注细枝末节。 "
......
我非常能理解小伙伴们的痛苦,因为我也是这么痛苦着走过来的。
在阅读由面向对象的语言如Java写的代码时,会发现接口和具体的实现经常对应不起来,不太清楚一个功能到底是怎么在哪个实现类中才能找到。 不像C语言,就是函数调用函数,相对还好点。
如果是动态语言如Ruby, Python,一个变量的类型甚至都不容易知道,阅读的难度大大增加。
还有一个重要的原因,现在我们看到的源码基本上都经过若干年发展、经过很多人不断地完善的,枝枝蔓蔓非常多,魔鬼都在细节中。 阅读的时候很容易陷进去, 看了几十层函数调用以后,就彻底懵了,就放弃了: 甭管你把源码吹得天花乱坠, 老子再也不看了。
经过很多痛苦的挣扎以后,我也算有一些成功的经历,今天用治学的三个境界来类比, 给大家分享一下:
怎样阅读源码?
昨夜西风凋碧树,独上高楼,望尽天涯路
想把源码搞懂,吃透,首先得登高望远,瞰察路径,明确目标与方向,了解源码的概貌。
1. 阅读源码之前,需要有一定的技术储备
比如设计模式,在很多Java源码中几乎就是标配,尤其是这几个:模板方法,单例,观察者,工厂方法,代理,策略,装饰者。
再比如阅读Spring源码,肯定得先了解IoC是怎么回事,AOP的实现方式,CGLib,Java动态代理等,自己动手,写点相关的代码,把这些知识点掌握了。
2. 必须得会使用这个框架/类库, 最好是精通各种各样的用法
魔鬼都在细节中,如果有些用法根本不知道,阅读源码就会显得比较困难
3. 了解这个软件的整体设计
都有哪些模块? 模块之间是怎么关联的?怎么关联的?
可能一下子理解不了,但是要建立一个整体的概念,就像一个地图,防止迷航。
在读源码的时候可以时不时看看自己在什么地方。
4. 搭建系统,把源代码跑起来!
相信我,Debug是非常非常重要的手段, 想通过只看而不运行就把系统搞清楚,那是根本不可能的!
衣带渐宽终不悔,为伊消得人憔悴。
5. 根据对系统的理解,设计几个主要的测试案例,定义好输入,输出
运行系统,慢慢地debug ,一步步地走,这是个死功夫,没有办法绕过。
Debug一遍肯定是不行的,需要Debug很多遍。
第一遍尽可能抛弃细节,抓住主要流程, 比如有些看起来不重要的方法就不进去看了。
第二遍、第三遍....再去看那些细节。
一个非常重要的工作就是记笔记(又是写作!),画出系统的类图(不要依靠IDE生成的), 记录下主要的函数调用, 方便后续查看。
文档工作极为重要,因为代码太复杂,人的大脑容量也有限,记不住所有的细节。 文档可以帮助你记住关键点, 到时候可以回想起来,迅速地接着往下看。
6. 主要的测试案例搞明白了,丰富测试案例,考虑一些分支流程
继续Debug......
总之,静态地看代码 + 动态地debug (从业务的角度), 就会慢慢揭开这个黑暗森林的面纱。
这一步会非常非常地花费时间,但是你做完了,对系统的理解绝对有质的飞跃。
众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
没有千百度的上下求索,不会有瞬间的顿悟和理解,衷心祝愿阅读源码的朋友们都能达到这一境界。
最后一点,也是最关键的一点: 要能坚持下去!!!
我不是一个聪明人, 但是笨人自有笨办法:什么事都架不住不断的重复,一遍看不明白,再来第二遍, 两遍搞不明白,再来第三遍......